JS中的this

this

this 关键字是函数运行时自动生成的一个内部对象,只能在函数内部使用,总指向调用它的对象

this在函数执行过程中,this一旦被确定了,就不可以再更改

绑定规则:

根据不同的使用场合,this有不同的值,主要分为下面几种情况:

  • 默认绑定

  • 隐式绑定

  • new绑定

  • 显示绑定

默认绑定

  var a=1
    function b() {
      console.log(this);//window
      return this.a
    }
    console.log(b());//1

 原因是调用函数的对象在游览器中位window,因此this指向window

注意:

严格模式下,不能将全局对象用于默认绑定,this会绑定到undefined,只有函数运行在非严格模式下,默认绑定才能绑定到全局对象

隐式绑定

函数还可以作为某个对象的方法调用,这时this就指这个上级对象

function test() {
      console.log(this.a);
    }
    var obj = {a:1};
    obj.c = test;
    obj.c(); // 1

new绑定

通过构建函数new关键字生成一个实例对象,此时this指向这个实例对象

function test() {
 this.x = 1;
}

var obj = new test();
obj.x // 1

显示修改

apply()、call()、bind()是函数的一个方法,作用是改变函数的调用对象。

作用

改变函数执行时的上下文,简而言之就是改变函数运行时的this指向

什么情况下需要改变this的指向呢?下面举个例子

const name="lucy";
const obj={
    name:"martin",
    say:function () {
        console.log(this.name);
    }
};
obj.say(); //martin,this指向obj对象
setTimeout(obj.say,0); //lucy,this指向window对象

从上面可以看到,正常情况say方法输出martin

但是我们把say放在setTimeout方法中,在定时器中是作为回调函数来执行的,因此回到主栈执行时是在全局执行上下文的环境中执行的,这时候this指向window,所以输出lucy

区别

apply(this指向谁,参数(以数组的形式))   立即执行   临时改变指向一次

apply接受两个参数,第一个参数是this的指向,第二个参数是函数接受的参数,以数组的形式传入

改变this指向后原函数会立即执行,且此方法只是临时改变this指向一次

 function test(...a) {
      console.log(this);//{name: 'zhang'}
      console.log(a);//[1, 2]
    }
    var obj = {name:'zhang'};
    test.apply(obj,[1,2])
call(this指向谁,参数列表)   立即执行   临时改变指向一次

call方法的第一个参数也是this的指向,后面传入的是一个参数列表

apply一样,改变this指向后原函数会立即执行,且此方法只是临时改变this指向一次

    function test(...a) {
      console.log(this);//{name: 'zhang'}
      console.log(a);// [1, 2, 3]
    }
    var obj = {name:'zhang'};
    test.call(obj,1,2,3)
bind(this指向谁,参数列表(多次传入))   立即执行   永久改变

bind方法和call很相似,第一参数也是this的指向,后面传入的也是一个参数列表(但是这个参数列表可以分多次传入)

改变this指向后不会立即执行,而是返回一个永久改变this指向的函数

 function test(...a) {
      console.log(this);
      console.log(a);
    }
    var obj = { name: 'zhang' };
    var d = test.bind(obj)
    console.log(d);//ƒ test(...a) { console.log(this);console.log(a);}
    d()//{name: 'zhang'}  []
    d(1, 2, 3, 5)//{name: 'zhang'}   [1, 2, 3, 5]
三者区别

相同点:

  1. 都能改变this的指向,
  2. 三者第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefinednull,则默认指向全局window
  3. 都可以传入参数

不同点:

  1. apply是数组,而call是参数列表,且applycall是一次性传入参数,而bind可以分为多次传入
  2. bind是返回绑定this之后的函数,applycall 则是立即执行

优先级

new绑定优先级 > 显示绑定优先级 > 隐式绑定优先级 > 默认绑定优先级

 

posted @ 2022-06-24 10:28  长安·念  阅读(71)  评论(0)    收藏  举报