1:this
跟大多數(shù)的語(yǔ)言一樣,javascript的this總是指向一個(gè)對(duì)象男应,而具體指向哪個(gè)對(duì)象是在運(yùn)行時(shí)基于函數(shù)的運(yùn)行環(huán)境動(dòng)態(tài)綁定的,而非被聲明時(shí)的環(huán)境娱仔。
2:this的指向
除去不常用的evel和with的情況沐飘,this指向大概分為以下四種
- 1:作為對(duì)象的方法調(diào)用,
- 2:作為普通函數(shù)調(diào)用牲迫,
- 3:構(gòu)造器調(diào)用耐朴,
- 4:Function.prototype.call或Function.prototype.apply調(diào)用
2.1:作為對(duì)象的方法調(diào)用
當(dāng)函數(shù)作為對(duì)象的方法被調(diào)用時(shí),this指向該對(duì)象盹憎;
var obj = {
a: 1,
getA:function () {
alert(this === obj);//true
alert(this.a)//a
}
};
obj.getA();
2.2:作為普通函數(shù)調(diào)用
當(dāng)函數(shù)不作為對(duì)象的屬性調(diào)用時(shí)筛峭,用普通的函數(shù)調(diào)用時(shí),此時(shí)的this總是指向全局對(duì)象陪每。在瀏覽器里全局對(duì)象就是window影晓;
var name = "globalName";
var getName = function () {
return this.name;
};
console.log(getName());//輸出:globalName
// 或者:
var myObject = {
name:"jiankui",
getName:function () {
return this.name;
}
};
var getName = myObject.getName ;
console.log(getName())//輸出:globalName
2.3:構(gòu)造器調(diào)用
除了一些內(nèi)置的函數(shù),大部分的javascript函數(shù)都可以當(dāng)做構(gòu)造器使用檩禾,構(gòu)造器的外表跟普通的函數(shù)一模一樣挂签,區(qū)別在于調(diào)用的方式,當(dāng)用new運(yùn)算符調(diào)用函數(shù)時(shí)盼产,改函數(shù)通常返回一個(gè)對(duì)象饵婆,構(gòu)造器的this就指向這個(gè)返回的對(duì)象
var myClass = function () {
this.name= "jiankui";
};
var obj = new myClass();
console.log(obj.name);//jiankui
但是用new構(gòu)造器時(shí),還要注意一個(gè)問(wèn)題戏售,如果構(gòu)造器顯式的返回一個(gè)object類(lèi)型的對(duì)象侨核,那么此次運(yùn)算結(jié)果最終會(huì)返回這個(gè)對(duì)象草穆,而不是我們上面期待的this
var myClass = function () {
this.name= "jiankui";
return {//顯式的返回一個(gè)對(duì)象
name: "jiankui2"
}
};
var obj = new myClass();
console.log(obj.name);//jiankui2
如果構(gòu)造器不顯式的返回任何數(shù)據(jù),或者是返回一個(gè)非對(duì)象類(lèi)型的數(shù)據(jù)搓译,就不會(huì)造成上述困擾
var myClass = function () {
this.name= "jiankui";
return "jiankui2";
};
var obj = new myClass();
console.log(obj.name);//jiankui
2.4:Function.prototype.call或Function.prototype.apply調(diào)用
跟普通函數(shù)調(diào)用相比悲柱,用Function.prototype.call或Function.prototype.apply可以動(dòng)態(tài)的改變傳入函數(shù)的this
var obj1 = {
name:"jiankui",
getName:function () {
return this.name;
}};
var obj2 = {
name:"jiankui2"
};
console.log(obj1.getName());//jiankui
console.log(obj1.getName.call(obj2));//jiankui2
3:丟失的this
這是個(gè)經(jīng)常遇到的問(wèn)題,先看代碼
var obj = {
name:"jiankui",
getName:function () {
return this.name;
}};
var getName2 =obj.getName;
console.log(obj.getName());//jiankui
console.log(getName2());//undefind
當(dāng)調(diào)用obj.getName()時(shí)些己,getName被當(dāng)做對(duì)象的方法調(diào)用诗祸,根據(jù)2.1提到的,this指向obj對(duì)象轴总,所以obj.getName()輸出jiankui直颅。
當(dāng)用另一個(gè)變量getName2()來(lái)引用obj.getName,并調(diào)用getName2()時(shí),根據(jù)2.2提到的怀樟,此時(shí)是作為普通函數(shù)調(diào)用功偿,this指向window,而我們的window沒(méi)有定義往堡,所以為undefined
4 call和apply
apply接收兩個(gè)參數(shù)械荷,第一個(gè)參數(shù)指定了函數(shù)體內(nèi)this對(duì)象的指向,第二個(gè)參數(shù)為一個(gè)帶下標(biāo)的集合虑灰,可以為數(shù)組和類(lèi)數(shù)組吨瞎,apply方法把這個(gè)集合中的元素作為參數(shù)傳入被調(diào)用的函數(shù):
var func = function (a, b, c) {
console.log([a, b, c]);//[1,2,3]
};
//數(shù)組的三個(gè)值分別對(duì)應(yīng)abc三個(gè)參數(shù)
func.apply(null,[1,2,3]);
call傳入的參數(shù)數(shù)量不固定,跟apply相同的是穆咐,第一個(gè)參數(shù)也是代表函數(shù)體內(nèi)的this指向颤诀,從第二個(gè)參數(shù)開(kāi)始往后,每個(gè)參數(shù)被依次傳入函數(shù)
var func = function (a, b, c) {
console.log([a, b, c]);//[1,2,3]
};
func.call(null,1,2,3);