JS里沒有類.
構(gòu)造函數(shù)是個函數(shù),this指向的是個對象,this蒙上眼睛指也指不到構(gòu)造函數(shù)去.
構(gòu)造函數(shù)的this指向創(chuàng)建的實(shí)例對象無疑.要明白這一點(diǎn),要先弄明白,用new操作符調(diào)用構(gòu)造函數(shù)的時候都發(fā)生了什么.
正好我有個答案是講構(gòu)造函數(shù)的,我這里原樣搬來:
造函數(shù)其實(shí)和普通函數(shù)本質(zhì)上并無區(qū)別,唯一的區(qū)別有兩個:
1.函數(shù)首字母大寫糊昙,這個區(qū)別只是約定俗成的咬清,便于區(qū)分李破。你實(shí)在要小寫定義構(gòu)造函數(shù)也完全沒問題构资,所以這個區(qū)別可以忽略乌妒。
2.構(gòu)造函數(shù)的調(diào)用需要用new操作符,而普通函數(shù)的調(diào)用又分很多種,但是都不會用到new操作符赋除。所以,構(gòu)造函數(shù)和普通函數(shù)的區(qū)別就在這個new操作符里非凌,現(xiàn)在讓我們來好好研究一下這個new操作符举农。
用new操作符創(chuàng)建對象時發(fā)生的事情:
第一步:創(chuàng)建一個Object對象實(shí)例。
第二步:將構(gòu)造函數(shù)的執(zhí)行對象賦給新生成的這個實(shí)例敞嗡。
第三步:執(zhí)行構(gòu)造函數(shù)中的代碼
第四步:返回新生成的對象實(shí)例
注意:原本的構(gòu)造函數(shù)是window對象的方法颁糟,如果不用new操作符而直接調(diào)用,那么構(gòu)造函數(shù)的執(zhí)行對象就是window喉悴,即this指向了window±饷玻現(xiàn)在用new操作符后,this就指向了新生成的對象箕肃。理解這一步至關(guān)重要婚脱。
執(zhí)行構(gòu)造函數(shù)中的代碼,看代碼:
functionPerson(){
this.name="Tiny Colder";
varage =22;
window.age =22;
}
varp =newPerson();
alert(p.name)//Tiny Colder;
alert(p.age)//undefined;
alert(window.age)//22;
當(dāng)用new操作符創(chuàng)建對象時勺像,先創(chuàng)建了一個對象實(shí)例障贸,然后執(zhí)行代碼。所以還在糾結(jié)吟宦,什么時候構(gòu)造函數(shù)定義的屬性會繼承給實(shí)例對象的篮洁,都可以這么來看:
varp=newObject();
p.name="Tiny Colder";
這是普通的創(chuàng)建對象,然后給對象添加屬性的方法殃姓。如果每創(chuàng)建一個對象袁波,都需要這么幾行代碼,無疑是糟糕的蜗侈。這個需求就正好跟這一點(diǎn)對應(yīng):new操作符篷牌,自動執(zhí)行構(gòu)造函數(shù)里的代碼。如此我們便可以省掉添加屬性時重復(fù)冗余的代碼宛篇。那么這些屬性時如何添加到新生成的對象里的呢娃磺?
第二個步驟里已經(jīng)說了:將構(gòu)造函數(shù)的執(zhí)行對象賦給新生成的這個實(shí)例。再結(jié)合上一段里說的叫倍,自動執(zhí)行構(gòu)造函數(shù)里的
this.name = "Tiny Colder";時偷卧,就相當(dāng)于是執(zhí)行p.name = "Tiny Colder";而構(gòu)造函數(shù)里的var age = 22;語句,會執(zhí)行但是對新生成的對象并無影響吆倦。window.age = 22;語句听诸,會執(zhí)行,且會給window對象添加一個屬性蚕泽。alert為證晌梨。
或許到這里桥嗤,你已經(jīng)理解了new操作符的前三步了,重要的三步仔蝌。但是這個函數(shù)是如何返回對象的呢泛领?我們并沒有看到有任何跟return相關(guān)的語句。這就是new操作符的最后一步:返回新生成的對象敛惊。如果被調(diào)用的函數(shù)沒有顯式的return表達(dá)式(僅限于返回對象)渊鞋,則隱式的會返回this對象-也就是新創(chuàng)建的對象。
現(xiàn)在來看一下這個代碼:
functionPerson(){
this.name="Tiny Colder";
return{};
}
varp =newPerson();
alert(p.name)//undefined;
一個對象就這么被創(chuàng)建出來了瞧挤。實(shí)際上锡宋,
varp =newPerson();
和
varp =newObject();
Person.apply(p);
是一樣的效果