深入了解javascript中的prototype與繼承
通常來說,javascript中的對象就是一個指向prototype的指針和一個自身的屬性列表。javascript創(chuàng)建對象時采用了寫時復(fù)制的理念。
只有構(gòu)造器才具有prototype屬性,原型鏈繼承就是創(chuàng)建一個新的指針,指向構(gòu)造器的prototype屬性。
prototype屬性之所以特別,是因為javascript時讀取屬性時的遍歷機制決定的。本質(zhì)上它就是一個普通的指針。
構(gòu)造器包括:
1.Object
2.Function
3.Array
4.Date
5.String
下面我們來舉一些例子吧
<script>
//每個function都有一個默認的屬性prototype,而這個prototype的constructor默認指向這個函數(shù)
//注意Person.constructor 不等于 Person.prototype.constructor. Function實例自帶constructor屬性
function Person(name) {
this.name = name;
};
Person.prototype.getName = function() {
return this.name;
};
var p = new Person("ZhangSan");
console.log(Person.prototype.constructor === Person); // true
console.log(p.constructor === Person); // true ,這是因為p本身不包含constructor屬性,所以這里其實調(diào)用的是Person.prototype.constructor
</script>
我們的目的是要表示
1.表明Person繼承自Animal
2. 表明p2是Person的實例
我們修改一下prototype屬性的指向,讓Person能獲取Animal中的prototype屬性中的方法。也就是Person繼承自Animal(人是野獸)
<script>
function Person(name) {
this.name = name;
};
Person.prototype.getName = function() {
return this.name;
};
var p1 = new Person("ZhangSan");
console.log(p.constructor === Person); // true
console.log(Person.prototype.constructor === Person); // true
function Animal(){ }
Person.prototype = new Animal();//之所以不采用Person.prototype = Animal.prototype,是因為new 還有其他功能,最后總結(jié)。
var p2 = new Person("ZhangSan");
//(p2 -> Person.prototype -> Animal.prototype, 所以p2.constructor其實就是Animal.prototype.constructor)
console.log(p2.constructor === Person); // 輸出為false ,但我們的本意是要這里為true的,表明p2是Person的實例。此時目的1達到了,目的2沒達到。
</script>
但如果我們這么修正
Person.prototype = new Animal();
Person.prototype.constructor = Person;
這時p2.consturctor是對了,指向的是Person,表示p2是Person類的實例,但是新問題出現(xiàn)了。此時目的2達到了,目的1沒達到。
目的1和目的2此時互相矛盾,是因為此時prototype表達了矛盾的兩個意思,
1表示父類是誰
2作為自己實例的原型來復(fù)制
因此我們不能直接使用prototype屬性來表示父類是誰,而是用getPrototypeOf()方法來知道父類是誰。
Person.prototype = new Animal();
Person.prototype.constructor = Person;
var p2 = new Person("ZhangSan");
p2.constructor //顯示 function Person() {}
Object.getPrototypeOf(Person.prototype).constructor //顯示 function Animal() {}
就把這兩個概念給分開了
最后總結(jié)一下:
當(dāng)代碼var p = new Person()執(zhí)行時,new 做了如下幾件事情:
創(chuàng)建一個空白對象
創(chuàng)建一個指向Person.prototype的指針
將這個對象通過this關(guān)鍵字傳遞到構(gòu)造函數(shù)中并執(zhí)行構(gòu)造函數(shù)。
如果采用Person.prototype = Animal.prototype來表示Person繼承自Animal, instanceof方法也同樣會顯示p也是Animal的實例,返回為true.之所以不采用此方法,是因為下面兩個原因:
1.new 創(chuàng)建了一個新對象,這樣就避免了設(shè)置Person.prototype.constructor = Person 的時候也會導(dǎo)致Animal.prototype.constructor的值變?yōu)镻erson,而是動態(tài)給這個新創(chuàng)建的對象一個constructor實例屬性,這樣實例上的屬性constructor就覆蓋了Animal.prototype.constructor,這樣Person.prototype.constructor和Animal.prototype.contructor就分開了。
2.Animal自身的this對象的屬性沒辦法傳遞給Person
通過使用 hasOwnProperty()方法,什么時候訪問的是實例屬性,什么時候訪問的是原型屬性就 一清二楚了。
相關(guān)文章
關(guān)于JavaScript中的關(guān)聯(lián)數(shù)組分析
本篇文章小編為大家介紹,關(guān)于JavaScript中的關(guān)聯(lián)數(shù)組分析。有需要的朋友可以參考一下2013-04-04
javascript中undefined與null的區(qū)別
這篇文章介紹了javascript中undefined與null的區(qū)別,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
javascript驗證form表單數(shù)據(jù)的案例詳解
這篇文章主要介紹了javascript驗證form表單數(shù)據(jù),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03
javascript input圖片上傳及預(yù)覽,FileReader預(yù)覽圖片
本文放置了html完成代碼案例,有需要大家可以直接復(fù)制測試功能,采用input文本框圖片上傳,使用FileReader預(yù)覽圖片效果2021-06-06

