在JavaScript中旗扑,this是當(dāng)前執(zhí)行函數(shù)的環(huán)境濒生。因?yàn)镴avaScript有4種不同的函數(shù)調(diào)用方式:
函數(shù)調(diào)用: alert('Hello World!')
方法調(diào)用: console.log('Hello World!')
構(gòu)造函數(shù)調(diào)用: new RegExp('\d')
隱式調(diào)用: alert.call(undefined, 'Hello World!')
并且每種方法都定義了自己的上下文完慧,this會(huì)表現(xiàn)得跟我們預(yù)期的不太一樣。同時(shí),strict模式也會(huì)影響函數(shù)執(zhí)行時(shí)的上下文锈遥。
理解this的關(guān)鍵點(diǎn)就是要對(duì)函數(shù)調(diào)用以及它所處的環(huán)境有個(gè)清晰的觀點(diǎn)纫事。這篇文章將會(huì)著重于對(duì)函數(shù)調(diào)用的解釋、函數(shù)調(diào)用如何影響this以及展示確定環(huán)境時(shí)常見(jiàn)的陷阱所灸。
下面列舉一些this常用的場(chǎng)景丽惶,希望可以對(duì)讀者有所幫助:
一、普通函數(shù)里的this指向:普通函數(shù)中的this指針指向于調(diào)用者爬立;
this 在函數(shù)調(diào)用中是一個(gè)全局對(duì)象钾唬,全局對(duì)象是由執(zhí)行的環(huán)境決定的。在瀏覽器里它是window對(duì)象侠驯。
function fn (){
??? this.name = '小璇';
??? console.log(this);?? // 此處打印window
? ? console.log(this.name);? // 此處打印小璇
}
fn()抡秆;
二、在定時(shí)器中的this的指向:
function CreatePerson () {
?????? this.name = '小璇';
?????? setInterval(function(){
? ? ? ?? console.log(this);
?}, 2000) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // ? this指向與構(gòu)造函數(shù)創(chuàng)建的對(duì)象:this的調(diào)用者是new
????? // setInterval(this.show, 2000); ? ? //? 由new來(lái)給定時(shí)器綁定一個(gè)函數(shù)
????? // setInterval(function(){ ? ? ? ? ?? ?? // this指向于window吟策;因?yàn)閠his是由定時(shí)器調(diào)起執(zhí)行的
????? //? ? console.log(this);
????? // }, 2000);???????????????????????????????? //把this的指向固定在self變量中
var slef = this;
????? setInterval(function(){???????????????? // 此時(shí)儒士,self指向的是對(duì)象
????????? self.show();
????? }, 2000);
}
CreatePerson.prototype.show = function (){
// console.log('hello');
console.log(this);
}
三、在對(duì)象方法中的this指針指向:
var name = '小李子';
var per = {
????? name: '小璇',
????? fn: function () {
???? ? ? ?? console.log(this.name);
?????? }
}
per.fn();?????????????? //this指針指向了per
var obj = per.fn;??
window.obj();? ? ? ? // fn方法交給了window對(duì)象調(diào)用檩坚,所以方法中的this指針指向了window對(duì)象
四着撩、在構(gòu)造函數(shù)中的調(diào)用:
function CreatePerson() {
this.name = '小璇';
// 如果在構(gòu)造函數(shù)中向外返回一個(gè)對(duì)象,則該對(duì)象會(huì)覆蓋由new創(chuàng)建出來(lái)的對(duì)象
// return {
//? ? name: '小李子'
// }
// 構(gòu)造函數(shù)不能向外返回引用類(lèi)型匾委,因?yàn)榉祷氐囊妙?lèi)型會(huì)替換掉new創(chuàng)建出來(lái)的對(duì)象
// 如果向外返回的是null對(duì)象睹酌,則不會(huì)替換
return null;
}
// 因?yàn)閚ew調(diào)用函數(shù)執(zhí)行時(shí):1、開(kāi)辟一塊內(nèi)存空間剩檀;2憋沿、把函數(shù)中this的指向指為這塊空間;3、把創(chuàng)建出來(lái)的空間交給變量
var per = new? CreatePerson();
console.log(per.name);
五沪猴、在事件函數(shù)中的this的指向:
function Btn() {
????? this.b = 23;???? 這里的this指向調(diào)用者new
????? var _this = this;? //凝固指針
????? document.getElementById('btn').onclick = function (){
????? // this.show();
????? _this.show();?? //這里的指針依舊是new辐啄,而不是點(diǎn)擊事件的標(biāo)簽
????? };
}
window.onload = function () {
????? new Btn();
}
六、事件函數(shù)中this的指向
var btn = document.querySelector('#btn');
btn.onclick = function () {
console.log(this);
// 如果事件函數(shù)中嵌套了函數(shù)运嗜,該函數(shù)又出現(xiàn)了this指針壶辜,則該指針指向window對(duì)象
?? hello()??? // 此時(shí)下方被調(diào)用的hello函數(shù)里的this指向window
// hello.call(this);??? //此時(shí)下方被調(diào)用的hello函數(shù)里this指向點(diǎn)擊事件的標(biāo)簽,使用call扭轉(zhuǎn)this的指向到當(dāng)前作用域的this担租;
}
function hello() {
this.style.backgroundColor = 'red';
}