什么是this?
this是函數(shù)內(nèi)部的另一個對象,this引用的是函數(shù)執(zhí)行的環(huán)境對象,換句話說,哪個對象執(zhí)行這個函數(shù),函數(shù)的this就指向誰!
window.color="blue";
var o={
color:"red" //字面量只有一行不能用引號
};
function sayColor(){
alert(this.color);
}
sayColor();
//sayColor.call(o);
o.sayColor=sayColor;//把函數(shù)賦給對象o
//函數(shù)不帶括號相當(dāng)于變量指針
o.sayColor();
sayColor();
的執(zhí)行環(huán)境是window,此時的this指向window,變量sayColor賦給o(函數(shù)名相當(dāng)于指針)然后執(zhí)行。
其實這里也可以通過sayColor的call方法,前面說了,this是函數(shù)內(nèi)的一個對象,call()
實際上等于設(shè)置函數(shù)體內(nèi)this對象的值,那么如果執(zhí)行sayColor.call(o)
代表this指向了o。
隱式原型和instanceof
原型鏈和繼承
所有的對象的原型鏈都會找到Object.prototype,因此所有的對象都會有Object.prototype的方法。這就是所謂的“繼承”。
執(zhí)行上下文
一段js代碼拿過來真正一句一句運(yùn)行之前,瀏覽器已經(jīng)做了一些“準(zhǔn)備工作”
在“準(zhǔn)備工作”中完成了哪些工作:
變量、函數(shù)表達(dá)式——變量聲明,默認(rèn)賦值為undefined;
this——賦值;
函數(shù)聲明——賦值;
這三種數(shù)據(jù)的準(zhǔn)備情況我們稱之為“執(zhí)行上下文”或者“執(zhí)行上下文環(huán)境”。
全面理解this
在一個函數(shù)上下文中,this由調(diào)用者提供,由調(diào)用函數(shù)的方式來決定。如果調(diào)用者函數(shù),被某一個對象所擁有,那么該函數(shù)在調(diào)用時,內(nèi)部的this指向該對象。如果函數(shù)獨(dú)立調(diào)用,那么該函數(shù)內(nèi)部的this,則指向undefined。但是在非嚴(yán)格模式中,當(dāng)this指向undefined時,它會被自動指向全局對象。
var a = 20;
var foo = {
a: 10,
getA: function () {
return this.a;
}
}
console.log(foo.getA()); // 10
var test = foo.getA;
console.log(test()); // 20
foo.getA()中,getA是調(diào)用者,他不是獨(dú)立調(diào)用,被對象foo所擁有,因此它的this指向了foo。而test()作為調(diào)用者,盡管他與foo.getA的引用相同,但是它是獨(dú)立調(diào)用的,因此this指向undefined,在非嚴(yán)格模式,自動轉(zhuǎn)向全局window。
構(gòu)造函數(shù)與原型方法上的this
function Person(name, age) {
// 這里的this指向了誰?
this.name = name;
this.age = age;
}
Person.prototype.getName = function() {
// 這里的this又指向了誰?
return this.name;
}
// 上面的2個this,是同一個嗎,他們是否指向了原型對象?
var p1 = new Person('Nick', 20);
p1.getName();
我們已經(jīng)知道,this,是在函數(shù)調(diào)用過程中確定,因此,搞明白new的過程中到底發(fā)生了什么就變得十分重要。
通過new操作符調(diào)用構(gòu)造函數(shù),會經(jīng)歷以下4個階段。
創(chuàng)建一個新的對象;
將構(gòu)造函數(shù)的this指向這個新對象;
指向構(gòu)造函數(shù)的代碼,為這個對象添加屬性,方法等;
返回新對象。
因此,當(dāng)new操作符調(diào)用構(gòu)造函數(shù)時,this其實指向的是這個新創(chuàng)建的對象,最后又將新的對象返回出來,被實例對象p1接收。因此,我們可以說,這個時候,構(gòu)造函數(shù)的this,指向了新的實例對象,p1。
而原型方法上的this就好理解多了,根據(jù)上邊對函數(shù)中this的定義,p1.getName()中的getName為調(diào)用者,他被p1所擁有,因此getName中的this,也是指向了p1。