全局上下文
無論是否在嚴格模式下,在全局執(zhí)行上下文中(在任何函數(shù)體外部)this 都指代全局對象。
console.log(this === window) // true
this.a = 1
console.log(window.a) // 1
函數(shù)上下文
在函數(shù)內(nèi)部,this的值取決于函數(shù)被調(diào)用的方式。
- 簡單調(diào)用
function fn1() {
return this
}
function fn2() {
"use strict"
return this
}
console.log(fn1()) // window
console.log(fn2()) // undefined
- call/apply調(diào)用
如果要想把this的值從一個上下文傳到另一個,就要用call或者apply方法。如果傳遞給 this 的值不是一個對象,JavaScript 會嘗試使用內(nèi)部 ToObject 操作將其轉(zhuǎn)換為對象。
// 將一個對象作為call和apply的第一個參數(shù),this會被綁定到這個對象。
var obj = {a: 'Custom'};
// 這個屬性是在global對象定義的。
var a = 'Global';
function whatsThis(arg) {
return this.a; // this的值取決于函數(shù)的調(diào)用方式
}
whatsThis(); // 'Global'
whatsThis.call(obj); // 'Custom'
whatsThis.apply(obj); // 'Custom'
whatsThis.apply(1); // 等價于 whatsThis.apply(new Number(1))
- bind方法
調(diào)用f.bind(someObject)會創(chuàng)建一個與f具有相同函數(shù)體和作用域的函數(shù),但是在這個新函數(shù)中,this將永久地被綁定到了bind的第一個參數(shù),無論這個函數(shù)是如何被調(diào)用的。
function f(){
return this.a;
}
var g = f.bind({a:"azerty"});
console.log(g()); // azerty
var h = g.bind({a:'yoo'}); // bind只生效一次!
console.log(h()); // azerty
var o = {a:37, f:f, g:g, h:h};
console.log(o.f(), o.g(), o.h()); // 37, azerty, azerty
- 箭頭函數(shù)
在箭頭函數(shù)中,this與封閉詞法上下文(外層函數(shù))的this保持一致。在全局代碼中,它將被設(shè)置為全局對象
// 創(chuàng)建一個含有bar方法的obj對象,
// bar返回一個函數(shù),
// 這個函數(shù)返回this,
// 這個返回的函數(shù)是以箭頭函數(shù)創(chuàng)建的,
// 所以它的this被永久綁定到了它外層函數(shù)的this。
// bar的值可以在調(diào)用中設(shè)置,這反過來又設(shè)置了返回函數(shù)的值。
var obj = {
bar: function() {
var x = (() => this);
return x;
}
};
// 作為obj對象的一個方法來調(diào)用bar,把它的this綁定到obj。
// 將返回的函數(shù)的引用賦值給fn。
var fn = obj.bar();
// 直接調(diào)用fn而不設(shè)置this,
// 通常(即不使用箭頭函數(shù)的情況)默認為全局對象
// 若在嚴格模式則為undefined
console.log(fn() === obj); // true
// 但是注意,如果你只是引用obj的方法,
// 而沒有調(diào)用它
var fn2 = obj.bar;
// 那么調(diào)用箭頭函數(shù)后,this指向window,因為它從 bar 繼承了this。
console.log(fn2()() == window); // true
- 作為對象的方法
當函數(shù)作為對象里的方法被調(diào)用時,它們的 this 是調(diào)用該函數(shù)的對象,且不受函數(shù)定義方式或位置的影響,表明函數(shù)是從o的f成員調(diào)用的才是重點。
var o = {prop: 37};
function independent() {
return this.prop;
}
o.f = independent;
console.log(o.f()); // logs 37
- 作為構(gòu)造函數(shù)
當一個函數(shù)用作構(gòu)造函數(shù)時(使用new關(guān)鍵字),它的this被綁定到正在構(gòu)造的新對象。 - 作為一個DOM事件處理函數(shù)
當函數(shù)被用作事件處理函數(shù)時,它的this指向觸發(fā)事件的元素 - 作為一個內(nèi)聯(lián)事件處理函數(shù)
當代碼被內(nèi)聯(lián)on-event 處理函數(shù)調(diào)用時,它的this指向監(jiān)聽器所在的DOM元素