如何正確判斷this的指向?

如果用一句話概括 this 的指向,那麼即是: 誰調用它,this 就指向誰。

但是僅通過這句話,我們很多時候並不能準確判斷 this 的指向。因此我們需要藉助一些規則去幫助自己:

this 的指向可以按照以下順序判斷:

全局環境中的 this

瀏覽器環境:無論是否在嚴格模式下,在全局執行環境中(在任何函數體外部)this 都指向全局對象 window;

node 環境:無論是否在嚴格模式下,在全局執行環境中(在任何函數體外部),this 都是空對象 {};

new 綁定的 this

如果是 new 綁定,並且構造函數中沒有返回 function 或者是 object,那麼 this 指向這個新對象。如下:

構造函數返回值不是 function 或 object。new Super() 返回的是 this 對象。

function Super(age) {
    this.age = age;
}

let instance = new Super('26');
console.log(instance.age); //26

構造函數返回值是 function 或 object,new Super()是返回的是Super種返回的對象。

function Super(age) {
    this.age = age;
    let obj = {a: '2'};
    return obj;
}

let instance = new Super('hello'); 
console.log(instance);//{ a: '2' }
console.log(instance.age); //undefined

是否【顯示綁定】(用 bind, call, apply 綁定),如果是,那麼this綁定的就是指定的對象

function info(){
    console.log(this.age);
}
var person = {
    age: 20,
    info
}
var age = 28;
var info = person.info;
info.call(person);   //20
info.apply(person);  //20
info.bind(person)(); //20

這裏同樣需要注意一種特殊情況,如果 call,apply 或者 bind 傳入的第一個參數值是 undefined 或者 null,嚴格模式下 this 的值爲傳入的值 null /undefined。非嚴格模式下,實際應用的默認綁定規則,this 指向全局對象(node環境爲global,瀏覽器環境爲window)。

function info(){
    //node環境中:非嚴格模式 global,嚴格模式爲null
    //瀏覽器環境中:非嚴格模式 window,嚴格模式爲null
    console.log(this);
    console.log(this.age);
}
var person = {
    age: 20,
    info
}
var age = 28;
var info = person.info;
//嚴格模式拋出錯誤;
//非嚴格模式,node下輸出undefined(因爲全局的age不會掛在 global 上)
//非嚴格模式。瀏覽器環境下輸出 28(因爲全局的age會掛在 window 上)
info.call(null);

【隱式綁定】,函數的調用是在某個對象上觸發的,即調用位置上存在上下文對象。典型的隱式調用爲: xxx.fn()

function info(){
    console.log(this.age);
}
var person = {
    age: 20,
    info
}
var age = 28;
person.info(); //20;執行的是隱式綁定

【默認綁定】,在不能應用其它綁定規則時使用的默認規則,通常是獨立函數調用

非嚴格模式: node環境,執行全局對象 global,瀏覽器環境,執行全局對象 window。

嚴格模式:執行 undefined

function info(){
    console.log(this.age);
}
var age = 28;
//嚴格模式;拋錯
//非嚴格模式,node下輸出 undefined(因爲全局的age不會掛在 global 上)
//非嚴格模式。瀏覽器環境下輸出 28(因爲全局的age會掛在 window 上)
info(); 

箭頭函數的情況:

箭頭函數沒有自己的this,繼承外層上下文綁定的this。

 

參考:https://github.com/YvetteLau/Blog/issues/35

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章