如果用一句話概括 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