非原創(chuàng):
想要確定this的指向弛说,需要分下列幾種情況進(jìn)行討論:
全局代碼中的this
函數(shù)中的this
其中函數(shù)中的this比較復(fù)雜,也更為常見特笋,下面會(huì)著重說明剃浇。
全局代碼中的 THIS
這個(gè)很好理解巾兆,就是指向全局對象window猎物,如果是嚴(yán)格模式則是undefined,下面為了簡便角塑,直接用global代替蔫磨,不再對是否是嚴(yán)格模式進(jìn)行區(qū)分。
this.a = 10
console.log(a) // 10
b = 20
console.log(this.b) // 20
var c = 30
console.log(this.c) // 30
函數(shù)中的 THIS
先上結(jié)論:
函數(shù)上下文中的this值由調(diào)用者提供圃伶,并由表達(dá)式的形式確定堤如;
如果在調(diào)用括號(hào)的左側(cè)存在引用類型的值,則將this設(shè)置為該引用類型的base對象窒朋;
在所有其他情況下搀罢,this的值始終設(shè)置為null,因?yàn)閚ull沒有意義侥猩,所以被隱式轉(zhuǎn)換為全局對象榔至。
結(jié)論中的細(xì)節(jié)下面將會(huì)介紹。
引用類型
為了理解方便欺劳,先介紹一個(gè)基本概念:
引用類型可以表示為對象唧取,base是屬性所屬的對象,propertyName是此對象中屬性的名字划提,strict表示是否為嚴(yán)格模式枫弟。
var foo = 10
function bar() {}
可以理解成:
var fooReference = {
? base: global,
? propertyName: 'foo'
}
var barReference = {
? base: global,
? propertyName: 'bar'
}
OK,那么下面再來兩個(gè) 融會(huì)貫通一下鹏往。
function foo() {
? ? console.log(this)
}
foo() // global
var fooReference = {
? ? base: global,
? ? propertyName: 'foo'
}
結(jié)論很顯然淡诗,括號(hào)左邊是foo函數(shù),即window.foo()伊履,引用類型韩容,那么this指向base,即global湾碎。
擴(kuò)展一下:
foo.prototype.constructor() // foo.prototype
var fooPrototypeConstructorReference = {
? base: foo.prototype,
? property?Name: 'constructor'
}
同樣的判斷方法~
再來一個(gè) :
function foo() {
? console.log(this.bar)
}
var x = { bar: 10 }
var y = { bar: 20 }
x.test = foo
y.test = foo
x.test() // 10
y.test() // 20
var xTestReference = {
? base: x,
? propertyName: 'test'
}
// y應(yīng)該不用再寫了吧
非引用類型
非引用類型就一句話:全局對象宙攻。
老規(guī)矩,舉 :
(function() {
? console.log(this) // null => global
})()
// 括號(hào)內(nèi)?為函數(shù)聲明介褥,并非引用
下面的? 可能會(huì)讓人困惑:
var foo = {
? bar: function() {
? ? console.log(this)
? }
}
foo.bar() // Reference, OK => foo
(foo.bar)() // Reference, OK => foo
(foo.bar = foo.bar)() // global
(false || foo.bar)() // global
(foo.bar, foo.bar)() // global
后三組由于進(jìn)行?了賦值和運(yùn)算座掘,因此base丟失递惋,他們其實(shí)都變成了函數(shù)聲明,因此類似于自執(zhí)行函數(shù)溢陪,this指向global萍虽。
另外兩種情況
還有兩種情況,如果作為構(gòu)造函數(shù)被調(diào)用形真,指向?qū)嵗瘜ο笊急啵蝗绻莄all和apply調(diào)用,指向?他們的參數(shù)咆霜。
一點(diǎn)想法
this的指向確實(shí)是個(gè)比較?麻煩的點(diǎn)邓馒,理解上不困難,但是有些點(diǎn)需要記憶蛾坯,我覺得比較合適的方式是光酣,在用到過程中學(xué)習(xí)this,比如react中為什么要在constructor中?bind(this)脉课,為什么Vue的組件中救军,data中的數(shù)據(jù)要寫在return中,通過這種方式具體的學(xué)習(xí)?this更加實(shí)際倘零。