迷一樣的 this

各種 this 常常令人非常迷惑,至今只能理解簡單的情況,對于復(fù)雜的情況 this 傳來傳去,綁來綁去。。。還是會暈,不能透徹的理解。

this is neither a reference to the function itself, nor is it a reference to the function's lexical scope.
this is actually a binding that is made when a function is invoked, and what it references is determined entirely by the call-site where the function is called.

this 既不指向函數(shù),也不指向函數(shù)的 scope, 而是在函數(shù)執(zhí)行時動態(tài)綁定到所處的上下文。

this 到底綁定到什么,有 4 種基本的情況:

Default Binding

function foo() {
    console.log( this.a );
}

var a = 2;

foo(); // 2

this 默認會綁定到 global 對象

function foo() {
    "use strict";

    console.log( this.a );
}

var a = 2;

foo(); // TypeError: `this` is `undefined`

只有在非嚴格模式下才允許 this 綁定到 global, 嚴格模式下不允許綁定到 global

Implicit Binding 隱式綁定

function foo() {
    console.log( this.a );
}

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

obj.foo(); // 2

用一個對象 obj 去調(diào)用函數(shù),這時 this 就綁定到函數(shù)所在的對象

Explicit Binding 顯示綁定

function foo() {
    console.log( this.a );
}

var obj = {
    a: 2
};

foo.call( obj ); // 2

通過 call 或 apply 顯示調(diào)用一個函數(shù)并傳遞一個對象進去,這時 this 就綁定到傳入的對象上。這種情況最好理解。

new Binding

function foo(a) {
    this.a = a;
}

var bar = new foo( 2 );
console.log( bar.a ); // 2

當用 new 調(diào)用一個函數(shù)時主要做了下面4件事

  1. a brand new object is created
  2. the newly constructed object is [[Prototype]]-linked
  3. the newly constructed object is set as the this binding for that function call
  4. unless the function returns its own alternate object, the new-invoked function call will automatically return the newly constructed object.

當用 new 調(diào)用一個函數(shù)時,底層默認會新建一個對象,this 會綁定到這個新建的對象上。默認函數(shù)會返回這個新建的對象,當然也可以返回其它的對象。

Determining the this binding for an executing function requires finding the direct call-site of that function. Once examined, four rules can be applied to the call-site, in this order of precedence:

  1. Called with new? Use the newly constructed object.

  2. Called with call or apply (or bind)? Use the specified object.

  3. Called with a context object owning the call? Use that context object.

  4. Default: undefined in strict mode, global object otherwise.

總結(jié)下來就是找到函數(shù)調(diào)用點,依次看看是否符合以上 4 條規(guī)則

  1. 如果用 new 調(diào)用, this 綁定到函數(shù)新建的對象上
  2. 顯示調(diào)用直接綁定到傳入的對象上
  3. 通過對象調(diào)用,綁定到函數(shù)所在的對象上
  4. 默認綁定到 global 對象

Lexical this

function foo() {
    // return an arrow function
    return () => {
        // `this` here is lexically adopted from `foo()`
        console.log( this.a );
    };
}
var obj1 = {
    a:100
};
var a = 200;
foo.call(obj1)(); // 100

arrow-functions adopt the this binding from the enclosing (function or global) scope.

ES6 的 => 函數(shù)中的 this 會綁定到它所在的 scope 的 this。這里就是 foo 的 this。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容