JavaScript原型繼承之基礎(chǔ)機(jī)制
由于語言設(shè)計上的原因,JavaScript 沒有真正意義上“類”的概念。而通常使用的 new 命令實例化對象的方法,其實是對原型對象的實例化。這一語言功能的本質(zhì)依賴于 JavaScript 特有的原型鏈(prototype chain)模式。
所以嚴(yán)格意義上說,JavaScript 是基于原型的面向?qū)ο笳Z言。也就是說,每個實例對象都具有一個原型。對象從該原型中繼承屬性和方法。
1、構(gòu)造函數(shù)
利用構(gòu)造函數(shù),可以簡單地創(chuàng)建對象。構(gòu)造函數(shù)內(nèi)的 this 關(guān)鍵字指向?qū)嵗龑ο蟊旧恚?/p>
- function People(name){
- this.name = name;
- }
使用 new 運(yùn)算符和構(gòu)造函數(shù)創(chuàng)建實例對象:
- var people = new People('小明');
- console.log(people.name); //小明
但如果創(chuàng)建了兩個實例,這兩個實例之間無法直接共享屬性和方法:
- var people1 = new People('小明');
- var people2 = new People('小王');
- people1.sex = 'male';
- console.log(people2.sex); //undefined
也就是說對象一旦被實例化,其屬性方法都獨(dú)立存在,對某個屬性的修改不會影響到其他實例。
2、Prototype
于是就有了 prototype 屬性,這個屬性是在生成實例對象時自動創(chuàng)建的。它本身又是一個對象,擁有能夠在實例間共享的屬性和方法。而實例本身的屬性和方法,則包含在構(gòu)造函數(shù)中。換句話說,構(gòu)造函數(shù)內(nèi)部的屬性和方法,在經(jīng)過實例化后都成為了本地的屬性和方法,而原型(prototype)中的屬性和方法在實例中只是一種引用,因此能夠被多個實例共享。
還是剛才那個構(gòu)造函數(shù),現(xiàn)在為它增加 prototype 屬性:
- People.prototype.sex = 'female';
- //或者寫成 People.prototype = {sex: 'female'};
- console.log(people1.sex); //male
- console.log(people2.sex); //female
People 構(gòu)造函數(shù)的 prototype 屬性參數(shù)會直接影響到 people1 和 people2 兩個實例。
但為什么 people1.sex 輸出 male 呢?這是由于在 JavaScript 中,原型關(guān)系以遞歸形式存在。對象的原型也是一個對象,而原型的本身也可能具有一個原型。原型的最高層級是全局的 Object 對象。
這就是說,一旦 people1.sex 被設(shè)置為 male 后,它在原型中對應(yīng)的值就無法被暴露出來。假如 people1.sex 本身沒有值,才會從構(gòu)造函數(shù)的 prototype 屬性中讀取,以此類推一級一級向上查找,直到 Object 對象。
注:使用 “null” 給對象賦值,可以銷毀自定義對象,釋放內(nèi)存資源。
原文:http://www.mangguo.org/javascript-prototype-inheritance-basic-mechanisms/
【編輯推薦】