this指向誰?
this永遠指向最終呼叫的函式所在的物件
① this指向的,永遠只可能是物件!
② this指向誰,永遠不取決於this寫在哪!而是取決於函式在哪呼叫。
③ this指向的物件,我們稱之為函式的上下文context,也叫函式的呼叫者。
1. 當直接呼叫函式時,this指向window
function Obj () {
console.log(this)
}
Obj() // window
複製程式碼
2. 函式為物件屬性時,this指向該物件
function Obj () {
console.log(this)
}
let obj = {
name: 'hello',
where: Obj
}
obj.where() // {name: "hello", where: ƒ}
複製程式碼
3. 建構函式中,this指向例項化物件
function Obj () {
console.log(this)
}
let obj = new Obj() // Obj{}
複製程式碼
4. 在setTimeout和setInterval,this永遠指向window
function Obj () {
setTimeout(function () {
console.log(this)
}, 100)
}
let obj = {
name: 'hello',
where: Obj
}
obj.where() // window
複製程式碼
為何在setTimeout和setInterval中this永遠指向window呢?下面專門瞭解一下
setTimeout和setInterval中this指向問題
由setTimeout()呼叫的程式碼執行在與所在函式完全分離的執行環境上。這會導致,這些程式碼中包含的 this 關鍵字在非嚴格模式會指向 window (或全域性)物件,嚴格模式下為 undefined
function Obj () {
this.checkThis = function () {
console.log(this)
},
this.checkThisLast = function () {
setTimeout(function() {
console.log(this)
},100)
}
}
let obj = new Obj()
obj.checkThis() // Obj{}
obj.checkThisLast() // window
複製程式碼
如何解決setTimeout和setInterval中this的指向問題呢?
變數儲存this
function Obj () {
let self = this, // this繫結給一個變數
this.checkThis = function () {
console.log(this)
},
this.checkThisLast = function () {
setTimeout(function() {
console.log(self)
},100)
}
}
let obj = new Obj()
obj.checkThis() // Obj{}
obj.checkThisLast() // Obj{}
複製程式碼
箭頭函式
箭頭函式不會建立自己的this,它只會從自己的作用域鏈的上一層繼承this
- 指向定義時所在的作用域,而不是指向執行時所在的作用域。
function Obj () {
this.checkThis = function () {
console.log(this)
},
this.checkThisLast = function () {
setTimeout(() => {
console.log(this)
},100)
}
}
let obj = new Obj()
obj.checkThis() // obj{}
obj.checkThisLast() // obj{}
複製程式碼
bind()繫結
bind()用法是將函式繫結到物件上,會建立新的函式,函式體內的this值會被繫結到傳入bind()的首個引數;f.bind(obj)相當於obj.f(),則f()的this指向obj
- call(),apply()可以實現同樣this繫結,但call()、apply()呼叫後立即執行,apply()需要接收陣列引數
function Obj () {
this.checkThis = function () {
console.log(this)
},
this.checkThisLast = function () {
setTimeout(function () {
console.log(this)
}.bind(this),100)
}
}
let obj = new Obj()
obj.checkThis() // obj{}
obj.checkThisLast() // obj{}
複製程式碼