3、this 指向

90 阅读2分钟

1、对 this 对象的理解

this 是执行上下文中的一个属性,它指向最后一次调用这个方法的对象。在实际开发中,this 的指向可以通过四种调用模式来判断。

1.1、this 指向有四种绑定规则

  1. 默认绑定规则:在全局当中指向 window;独立调用也指向 window
  2. 隐式绑定规则:谁调用就指向谁
  3. 显式绑定规则:call、bind、apply
  4. new 绑定(构造器调用模式) 优先级: new绑定 > 显式绑定规则 > 隐式绑定规则 > 默认绑定规则

1.2、默认绑定规则

在全局中:

console.log(this === window); // true

在函数中:

function test() { 
    console.log(this === window); 
    } 
    
// 函数的独立调用: 
test();  // true
window.test(); // true

1.3、隐式绑定规则

每个函数在执行的时候就会有自身的一个this指向,可能值相同,但他们是不同的;也可以这么说:如果一个函数作为一个对象的方法来调用时,this 指向这个对象。
例子1:

var a = 0; 
var obj = { 
    a: 2, 
    foo: function() { 
        console.log(this); -> 指向 obj
        
        function test() { 
            console.log(this); -> 指向 window 
            } 
            
        test(); -> 这里是独立调用 
     } 
 } 
 
 obj.foo(); -> 这里是 obj 调用

打印:

image.png

例子2:

// 在浏览器环境,只要是立即执行函数 -> 相当于独立调用,指向全都是 window; 
// 还需分 node 环境,模块化环境,严格模式环境 

(function() { 
    console.log(this) -> 指向 window 
    })()

例子3: 闭包:当函数执行时,导致函数被定义,并被抛出

var obj = { 
    a: 2, 
    foo: function() {                                // 函数执行
        console.log(this); -> 指向 obj 
        
        // 这就是闭包: 
        function test() {                           // 被定义 
            console.log(this); -> 指向 window 
        } 
        
        return test;                               // 抛出 
    } 
 } 
 
 obj.foo()(); -> 这里第二个()是为了执行 test()

例子4: 变量赋值的情况

var a = 0; 
function foo() { 
    console.log(this); 
    } 
    
    var obj = { 
        a: 2; 
        foo: foo; 
    }
    
    obj.foo() -> 指向 obj 
    
    var bar = obj.foo; 
    // 完成赋值后,bar 已经和 obj 没有任何联系,给了一个 foo 函数,但没有执行 
    
    bar();
    // 函数在此执行,在 window 下执行,为全局 -> this指向window

例子5:
参数赋值的情况

var a = 0; 
function foo() { 
    console.log(this); -> 指向 window 
} 

function bar(fn) { 
    fn(); -> 独立调用 
    fn.call(obj); -> 指向 obj 
} 

var obj = { 
    a: 2, foo: foo; 
} 

bar(obj.foo)

1.4、显式绑定规则:call、bind、apply

1.4.1、 call() 和 apply() 的区别 \

它们的作用一模一样,区别仅在于传入参数的形式的不同。

  • apply 接受两个参数,第一个参数指定了函数体内 this 对象的指向,第二个参数为一个带下标的集合,这个集合可以为数组,也可以为类数组,apply 方法把这个集合中的元素作为参数传递给被调用的函数。
  • call 传入的参数数量不固定,跟 apply 相同的是,第一个参数也是代表函数体内的 this 指向,从第二个参数开始往后,每个参数被依次传入函数。