this
JavaScript里面的this總是指向一個對象撼玄,而具體指向哪個對象是在運行時基于函數(shù)的執(zhí)行環(huán)境動態(tài)綁定的,而非函數(shù)被聲明時的環(huán)境蜈漓。
大致分為下面四種:
- 作為對象的方法調(diào)用
- 作為普通函數(shù)調(diào)用
- 構(gòu)造器調(diào)用
- Function.prototype.call 或 Function.prototype.apply調(diào)用
1.作為對象的方法調(diào)用
var obj = {
name : 'zs',
getName : function(){
console.log(this === obj);//true
console.log(this.name);//zs
}
};
obj.getName();
2.作為普通函數(shù)調(diào)用
var name = 'zs';
var getName = function(){
return this.name;
}
console.log(getName());// return zs 這里的調(diào)用等同于window.getName() 所以this指向window對象
var age = 18;
var Obj = {
age : 22,
getAge : function(){
return this.age;
}
};
var getAggetAgee = Obj.getAge;
console.log(getAge());// return 18 這里也是在全局環(huán)境下面調(diào)用getAge,所以this也是指向window
//大致來說穆桂,this指向當(dāng)前函數(shù)被調(diào)用的那個環(huán)境。上面兩個方法都是在window下面被調(diào)用融虽,所以this就指向了window
還有一種情況是享完,我們有時需要在回調(diào)函數(shù)里面使用this,但這個時候this往往不是我們預(yù)期的那個樣子有额。這個時候般又,我們可以使用一個變量先保存this
var obj = {
name : 'zs',
getName : function(){
return this.name;
},
bindEvent : function(){
var that = this;
document.getElementById('dom').addEventListener('click',function(){
console.log(that.getName());
})
}
}
obj.bindEvent();//this.getName is not a function 這里的this指向了這個dom元素,所以找不到getName方法
//可以使用下面這種方法解決
bindEvent : function(){
var that = this;
document.getElementById('dom').addEventListener('click',function(){
console.log(that.getName());
})
}
3.構(gòu)造器調(diào)用
JavaScript中沒有類巍佑,但是可以通過構(gòu)造器創(chuàng)建對象茴迁,同時也提供了new運算符,使的構(gòu)造器看起來更像一個類萤衰。
在JS中堕义,除了瀏覽器提供的一些內(nèi)置函數(shù),大部分JavaScript函數(shù)都可以當(dāng)做構(gòu)造器使用脆栋。構(gòu)造器的外表和普通函數(shù)基本一模一樣胳螟,區(qū)別主要在于被調(diào)用的方式。當(dāng)使用new運算符調(diào)用函數(shù)時筹吐,這個函數(shù)就可以理解為構(gòu)造函數(shù)(其實只是構(gòu)造調(diào)用,和普通的函數(shù)還是一樣的秘遏,只是調(diào)用的方式不一樣)丘薛,該函數(shù)總會返回一個對象,通常情況下邦危,構(gòu)造器里的this就指向返回的這個函數(shù)
var MyFunc = function(){
this.name = 'zs';
}
var func = new MyFunc();
console.log(func.name);//return zs
需要注意:如果使用new調(diào)用構(gòu)造函數(shù)時洋侨,構(gòu)造函數(shù)主動返回了一個object類型的對象舍扰,那么此次的運算結(jié)果最終會返回這個對象,而不是我們之前期待的this
var MyFunc = function(){
this.name = 'zs';
return {
name : 'ls'
}
}
var func = new MyFunc();
console.log(func.name);//return ls
如果構(gòu)造器不顯示的返回任何數(shù)據(jù)希坚,或者是返回一個非對象類型的數(shù)據(jù)边苹,就不會造成上面的問題(例如:上面那里如果是
return '123'
,是不會造成問題的)
4.Function.prototype.call和Function.prototype.apply調(diào)用
和普通的函數(shù)調(diào)用相比,call和apply可以動態(tài)的改變傳入的this,他們的區(qū)別主要在接受的參數(shù)格式上
如果傳入的第一個參數(shù)為null裁僧,函數(shù)體內(nèi)的this會指向默認(rèn)的宿主對象个束,瀏覽器里面是window
call(this,arg1,arg2...)
apply(this,[arg1,arg2])
var obj = {
name : 'zs',
getName : function(){
return this.name;
}
};
var anotherObj = {
name : 'ls'
};
console.log(obj.getName());//return zs
console.log(obj.getName.call(anotherObj));// return ls
Math.max.apply(null,[1,2,3,4]);//4