在JavaScript中,this是當前執行函數的環境。因為JavaScript有4種不同的函數調用方式:
函數調用: alert('Hello World!')
方法調用: console.log('Hello World!')
構造函數調用: new RegExp('\d')
隱式調用: alert.call(undefined, 'Hello World!')
并且每種方法都定義了自己的上下文,this會表現得跟我們預期的不太一樣。同時,strict模式也會影響函數執行時的上下文。
理解this的關鍵點就是要對函數調用以及它所處的環境有個清晰的觀點。這篇文章將會著重于對函數調用的解釋、函數調用如何影響this以及展示確定環境時常見的陷阱。
下面列舉一些this常用的場景,希望可以對讀者有所幫助:
一、普通函數里的this指向:普通函數中的this指針指向于調用者;
this 在函數調用中是一個全局對象,全局對象是由執行的環境決定的。在瀏覽器里它是window對象。
function fn (){
??? this.name = '小璇';
??? console.log(this);?? // 此處打印window
? ? console.log(this.name);? // 此處打印小璇
}
fn();
二、在定時器中的this的指向:
function CreatePerson () {
?????? this.name = '小璇';
?????? setInterval(function(){
? ? ? ?? console.log(this);
?}, 2000) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // ? this指向與構造函數創建的對象:this的調用者是new
????? // setInterval(this.show, 2000); ? ? //? 由new來給定時器綁定一個函數
????? // setInterval(function(){ ? ? ? ? ?? ?? // this指向于window;因為this是由定時器調起執行的
????? //? ? console.log(this);
????? // }, 2000);???????????????????????????????? //把this的指向固定在self變量中
var slef = this;
????? setInterval(function(){???????????????? // 此時,self指向的是對象
????????? self.show();
????? }, 2000);
}
CreatePerson.prototype.show = function (){
// console.log('hello');
console.log(this);
}
三、在對象方法中的this指針指向:
var name = '小李子';
var per = {
????? name: '小璇',
????? fn: function () {
???? ? ? ?? console.log(this.name);
?????? }
}
per.fn();?????????????? //this指針指向了per
var obj = per.fn;??
window.obj();? ? ? ? // fn方法交給了window對象調用,所以方法中的this指針指向了window對象
四、在構造函數中的調用:
function CreatePerson() {
this.name = '小璇';
// 如果在構造函數中向外返回一個對象,則該對象會覆蓋由new創建出來的對象
// return {
//? ? name: '小李子'
// }
// 構造函數不能向外返回引用類型,因為返回的引用類型會替換掉new創建出來的對象
// 如果向外返回的是null對象,則不會替換
return null;
}
// 因為new調用函數執行時:1、開辟一塊內存空間;2、把函數中this的指向指為這塊空間;3、把創建出來的空間交給變量
var per = new? CreatePerson();
console.log(per.name);
五、在事件函數中的this的指向:
function Btn() {
????? this.b = 23;???? 這里的this指向調用者new
????? var _this = this;? //凝固指針
????? document.getElementById('btn').onclick = function (){
????? // this.show();
????? _this.show();?? //這里的指針依舊是new,而不是點擊事件的標簽
????? };
}
window.onload = function () {
????? new Btn();
}
六、事件函數中this的指向
var btn = document.querySelector('#btn');
btn.onclick = function () {
console.log(this);
// 如果事件函數中嵌套了函數,該函數又出現了this指針,則該指針指向window對象
?? hello()??? // 此時下方被調用的hello函數里的this指向window
// hello.call(this);??? //此時下方被調用的hello函數里this指向點擊事件的標簽,使用call扭轉this的指向到當前作用域的this;
}
function hello() {
this.style.backgroundColor = 'red';
}