9.4 this,this指向

发布于:2025-09-08 ⋅ 阅读:(22) ⋅ 点赞:(0)

什么是this

  • this是Javascript语言的一个关键字
  • 它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。
  • 随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,那就是this指的是,调用函数的那个对象

this的多种用法

  • 全局范围内

  • 函数调用

  • 作为对象方法的调用

  • call/apply/bind 的调用

  • 作为构造函数调用

全局范围内使用this

在全局范围内使用this ,它将指向全局对象(浏览器中为 window)

var name = 'name1';
console.log(name);
 
this.name = 'name2';
console.log(name);
console.log(this.name);
 
window.name = 'name3';
console.log(name);
console.log(this.name);
console.log(window.name);
纯粹的函数调用

这是函数的最通常用法,属于全局性调用,因此this就代表全局对象Global

// 案例1
function test(){
  this.x = 1;
  alert(this.x);
}
test(); // 1
// 案例2
var x = 1;
function test(){
  alert(this.x);
}
test(); // 1
// 案例3
var x = 1;
function test(){
  this.x = 0;
}
test();
alert(x); //0
在事件中表示当前元素的时候,可以使用this
var btn = document.getElementById("btn");
btn.onclick = function() {
     this.value = "按鈕";   //给btn注册的事件,因此this表示btn
}
在html结构中的this,指向的绑定事件的元素本身
<button onclick = "fun(this)">
    点击
</button>
<script>
    function fun(_this){
        console.log(_this); // 当前元素
    }
</script>
对象中的this

字面量对象中的this:指的就是对象本身

var obj = {
  name:'jack',
  say:function(){
    console.log('obj中的this',this.name);
  }
}
obj.say()
定时器中的this
<style>
  #box1{
    width: 200px;
    height: 200px;
    border: 1px solid #f00;
  }
</style>
<body>
    <div id="box1"></div>
<script>
    var str = '每一种食物,都是大自然的馈赠,也离不开姐姐的栽培。看着这一片绿油油的蔬菜,真的很令人羡慕,也有不少网友评论:这就是最好的生活。';
    box1.onclick = function(){
        var num = 0;
        setInterval(function(){
            num++;
            box1.innerHTML = str.substring(0,num);
            // 在定时器中的this是window,因为setInterval,其实是window.setInterval()
            this.innerHTML = str.substring(0,num);
        },100);
    }

  // 解决方案一:自定义一个变量_self来存储this
  box1.onclick = function(){
    var _this = this; // 把this对象对应的地址存储到_this中
    var num = 0;
    setInterval(function(){
      num++;
      box1.innerHTML = str.substring(0,num);
      _this.innerHTML = str.substring(0,num);
    },100);
  }

  // 解决方案二:使用箭头函数来解决
  // 箭头函数是函数表达式的简略的写法
  // 箭头函数中是没有this指向的,箭头中的函数指向是由定义他的作用域来决定this是谁(谁定义了箭头函数,this是谁)
  box1.onclick = function(){
    // 箭头函数是在这个事件监听函数中被定义出来的,所以箭头函数中的this,就是事件监听的this
    var num = 0;
    setInterval(()=>{
      num++;
      box1.innerHTML = str.substring(0,num);
      this.innerHTML = str.substring(0,num);
    },100);
  }
</script>
箭头函数中的this
  • 箭头函数会捕获其所在上下文的 this 值,作为自己的 this 值,自己本身并没有this值;

  • 箭头函数的this永远指向其上下文的this,任何方法都改变不了其指向,如call(), bind(), apply()。

call和apply中的this

call和apply 中的this指的是当前元素本身,传递进去之后,会修改方法里面的this指向

总结:非箭头函数情况下,分为两种情况:

1.this指向调用函数或者变量的对象(并且采取就近原则)

2.定时器的this永远指向window,除非使用bind等函数人为的改变指向

call(),apply(),bind() 方法

所有函数都是对象,都有call(),apply(),bind()方法,都是为了改变this指向

call方法

语法格式:fun.call(this,obj1,obj2);

JS中充满了各种各样的简写,其实这个调用也是一个简写 思考:默认情况下fun中的this指向哪里

function fun(){
  console.log(this);
}
box1.onclick = function(){
    fun();
}

思考:如何将fun中的this改变为box1?

function fun(){
  console.log(this);
}
box1.onclick = function(){
  fun.call(this); // 使用call,修改this指向
}

如果想要传递参数,可以写在this的后面

function fun2(a,b){
  console.log(a+b);
  console.log(this);
}
box1.onclick = function(){
  fun2.call(this,10,20)
}

案例:页面中有两个div容器,点击容器的时候,分别渲染进去不同的内容

<style>
  div{
    width: 200px;
    height: 200px;
    border: 1px solid #f00;
  }
</style>
<div id="box1"></div>
<div id="box2"></div>
<script>
  var data1 = ['red','blue','green'];
  var data2 = ['apple','banana','orange'];
  function render(data){
    var html = '<ul>';
    for(var i=0;i<3;i++){
      html += "<li>"+data[i]+"</li>";
    }
    html += "</ul>";
    this.innerHTML = html;
  }
  box1.onclick = function(){
      render(data1); // 不能显示
      render.call(this,data1);
  }
  box2.onclick = function(){
      render(data2); // 不能显示
      render.call(this,data2);
  }
</script>
apply方法

call和apply相似,不同指出在于传递的方式不同,call的参数需要逐个列举,apply的参数需要通过数组的形式传递

语法格式:fun.apply(this,[obj1,obj2]);

function fun(){
  console.log(this);
}
function fun2(a,b){
  console.log(a+b);
  console.log(this);
}
box1.onclick = function(){
  fun.apply(this)
  fun2.apply(this,[10,20])
}

apply虽然传递的是数组,但是接收的时候还是一个个接收的,所以10和20会分别被传递给a和b

案例:思考,如何在数组中获取数组中的最大值

var arr = [56,76,45,34,87,98];
var max = Math.max(arr); // 不能使用
var max = Math.max(arr[0],arr[1],arr[2]); // 可以使用,太麻烦
var max = Math.max.apply(null,arr); // 最优解
var max = Math.max(...arr); // 最优解
console.log(max);
bind方法

bind有两个特点

  1. 不会调用函数

  2. 可以改变函数内部this指向

bind()方法不会调用函数,但是能改变函数内部this指向

语法格式:Fun.bind(this,arg1,arg2);

案例一:改变fun中的this指向

function fun() {
    console.log(this);
}
box1.onclick = function () {
    // 把当前事件中的this指向传递给fun函数
    var aa = fun.bind(this);
    aa();
}

带参数的bind调用

function fun2(a, b) {
    console.log(a + b);
    console.log(this);
}
box1.onclick = function () {
    // bind传參的格式和call是一样的,直接用逗号隔开
    var aa = fun2.bind(this,10,20)
    aa();
}

思考:将fun函数中的this,修改为Obj对象

var Obj = {
    name:'jack',
    age:18
}
function fun() {
    console.log(this);
}
// 把fun中的this指向,只想到Obj身上
var newFun = fun.bind(Obj);
newFun(); // 这时候fun中的this,就变成了obj

注意:bind虽然可以改变this指向,但是不会自动调用,需要手动添加调用方式

面试题call,apply,bind有什么区别:call 和 apply 特性一样

都是用来调用函数,而且是立即调用

但是可以在调用函数的同时,通过第一个参数指定函数内部 this 的指向 call 调用的时候,参数必须以参数列表的形式进行传递,也就是以逗号分隔的方式依次传递即可 apply 调用的时候,参数必须是一个数组,然后在执行的时候,会将数组内部的元素一个一个拿出来,与形参一一对应进行传递 如果第一个参数指定了 null 或者 undefined 则内部 this 指向 window

bind可以用来指定内部 this 的指向,然后生成一个改变了 this 指向的新的函数

它和 call、apply 最大的区别是:bind 不会自动调用


网站公告

今日签到

点亮在社区的每一天
去签到