目錄 一個特例 在正式開始之前,我們先來說一個特例。 在構造函數中,this上的值會在創建實例的時候被綁定到新創建的實例上。不適用於下麵的判斷方法,所以特此說明。 開始判斷 下麵是一個典型例子,我們的分析從這裡開始。 法則一:對象方法中的this指向對象本身(箭頭函數形式的除外) 法則二:多層嵌套函 ...
目錄
* 一個特例
* 開始判斷
* 法則一:對象方法中的this指向對象本身(箭頭函數形式的除外)
* 法則二:多層嵌套函數中的this指向等同於包含該this的最近一個function的this
* 法則三:箭頭函數以及非指向對象方法中的function的情況下this指向window
* 習題集
* 普通函數中的this
* 函數執行後返回另外一個函數中的this(普通函數中)
* 多層嵌套函數中的this(定時器&箭頭函數)1
* 多層嵌套函數中的this(定時器&箭頭函數)2
一個特例
在正式開始之前,我們先來說一個特例。
// 構造函數
function Student(name) {
this.name = name
}
// 創建小明和小紅兩個實例
var XM = new Student('xiaoming')
var XH = new Student('xiaohong')
// 輸出信息
console.log(XM) // Student {name: "xiaoming"}
console.log(XH) // Student {name: "xiaohong"}
在構造函數中,this上的值會在創建實例的時候被綁定到新創建的實例上。不適用於下麵的判斷方法,所以特此說明。
開始判斷
下麵是一個典型例子,我們的分析從這裡開始。
var x = {
name: 'bw2',
getName1: function() {
console.log(this)
},
getName2: function() {
setTimeout(() => {
console.log(this)
},0)
},
getName31: () => {
console.log(this)
},
getName32: function() {
return function() {
console.log(this)
}
}
}
x.getName1() // {name: "bw2", getName1: ƒ}
x.getName2() // {name: "bw2", getName1: ƒ}
x.getName31() // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}
x.getName32()() // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}
法則一:對象方法中的this指向對象本身(箭頭函數形式的除外)
var x = {
name: 'bw2',
getName1: function() {
console.log(this)
}
}
x.getName1() // {name: "bw2", getName1: ƒ}
法則二:多層嵌套函數中的this指向等同於包含該this的最近一個function的this
箭頭函數沒有獨立的this作用域,所以繼續往外層走,走到了getName: function(){}。那麼就是他了,this指向等同於這個function內部的this指向。根據法則一,this指向對象本身。
var x = {
name: 'bw2',
getName2: function() {
console.log(this) // 等同於此處的this
setTimeout(() => {
console.log(this) // 原始的this位置
},0)
}
}
x.getName2() // {name: 'bw2', getName1: ƒ}
我們可以試著在瀏覽器中運行,看看結果。
法則三:箭頭函數以及非指向對象方法中的function的情況下this指向window
根據法則二,this是指向最近的function,因此,這裡的this等同於返回的函數中的this,不是對象方法中的this,所以,指向全局。
是不是感覺有點奇怪?不過實踐證明確實如此。
var x = {
name: 'bw2',
getName31: () => {
console.log(this)
},
getName32: function() {
return function() {
console.log(this)
}
}
}
x.getName31() // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}
x.getName32()() // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}
習題集
歡迎大家按照法則一到三依次判斷,猜測結果,併在瀏覽器下測試。測試結果也可以回覆,大家一起討論。
因本人能力有限,該系列法則可能在部分情況下失效。歡迎大家一起討論。
下麵是做題時間。
普通函數中的this
function x() {
console.log(this)
}
x()
函數執行後返回另外一個函數中的this(普通函數中)
function xx(){
return function() {
console.log(this)
}
}
xx()()
多層嵌套函數中的this(定時器&箭頭函數)1
var x = {
name: 'bw2',
getName: () => {
setTimeout(() => {
console.log(this)
},0)
}
}
x.getName()
多層嵌套函數中的this(定時器&箭頭函數)2
var x = {
name: 'bw2',
getName: () => {
setTimeout(function() {
console.log(this)
},0)
}
}
x.getName()
再次說明,該法則為實驗性法則,未進行大範圍的測試,不保證在所有情況下都有一致的結果。如果你發現了法則判斷失敗的情況,歡迎留言,一起探討。
歡迎關註前端進階指南微信公眾號:
另外我也創了一個對應的QQ群:660112451,歡迎一起交流。