1.簡述this
執(zhí)行上下文中包含了變量環(huán)境、 詞法環(huán)境、外部環(huán)境,this
當(dāng)一段代碼被執(zhí)行時,JavaScript引擎先會對其進(jìn)行編譯,并創(chuàng)建執(zhí)行上下文,以下3種情況都會被創(chuàng)建執(zhí)行上下文:
1.當(dāng)JavaScript執(zhí)行全局代碼的時候,會編譯全局代碼并創(chuàng)建全局執(zhí)行上下文,而且在整個?面的生存周期內(nèi),全局執(zhí)行上下文只有一份。
2.當(dāng)調(diào)用一個函數(shù)的時候,函數(shù)體內(nèi)的代碼會被編譯,并創(chuàng)建函數(shù)執(zhí)行上下文,一般情況下,函數(shù)執(zhí)行結(jié) 束之后,創(chuàng)建的函數(shù)執(zhí)行上下文會被銷毀。
3.當(dāng)使用eval函數(shù)的時候,eval的代碼也會被編譯,并創(chuàng)建執(zhí)行上下文。
2.this的指向
1.全局執(zhí)行上下文中的this,指向window
2.函數(shù)執(zhí)行上下文中的this
2.1.作為函數(shù)調(diào)用,嚴(yán)格模式下為undefined,非嚴(yán)格模式下為window
2.2.作為方法調(diào)用,指向調(diào)用的對象
var calculator={
operand1:1,
operand2:1,
add:function(){
this.result=this.operand1+this.operand2;
}
}
calculator.add();//這個方法調(diào)用1+1的結(jié)果,此時add 方法里面的this指向?qū)ο骳alculator
2.3.作為構(gòu)造函數(shù)調(diào)用,指向?qū)嵗?br> 2.4.間接調(diào)用,通過call和apply方法顯示傳入對象,此時this指向傳入的對象
3.改變函數(shù)中this的指向
- 通過函數(shù)的call、apply、bind方法設(shè)置
- 通過對象調(diào)用方法設(shè)置
- 通過構(gòu)造函數(shù)中設(shè)置
4.this的設(shè)計缺陷以及應(yīng)對方案
- 嵌套函數(shù)中的this不會從外層函數(shù)中繼承
解決:
外層函數(shù)聲明一個變量self用來保存this,內(nèi)層函數(shù)直接使用self變量
var myObj = {
name : "極客時間",
showThis: function(){
console.log(this)
var self = this
function bar(){
self.name = "極客邦" ;
}
bar()
}
}
myObj.showThis()
console.log(myObj.name) // 極客幫
console.log(window.name) //undefined
或者用es6的箭頭函數(shù)
var myObj = {
name : "極客時間",
showThis: function(){
console.log(this)
var bar = ()=>{
this.name = "極客邦"
console.log(this)
}
bar()
}
}
myObj.showThis()
- 普通函數(shù)中的this默認(rèn)指向全局對象window