理解JavaScript原型

JavaScript的原型是JavaScript中的重要一環(huán)粥血,根據(jù)網(wǎng)上的一些資料和自己的理解,對原型做一個解釋缭嫡。

prototype屬性的引入

對象可以使用new操作符后跟一個構(gòu)造函數(shù)來創(chuàng)建的缔御。構(gòu)造函數(shù)如下:

function Person(age) {
  this.name = "meng";
  this.age = age;
}

構(gòu)造函數(shù)始終都應(yīng)該以一個大寫字母開頭,而非構(gòu)造函數(shù)則應(yīng)該以一個小寫字母開頭械巡。要創(chuàng)建一個新的實(shí)例對象的時候刹淌,可以使用new操作符。

var person1 = new Person(12);
var person2 = new Person(13);

在構(gòu)建的兩個實(shí)例對象的時候讥耗,person1和person2有一個共有屬性name;當(dāng)改變其中一個實(shí)例對象的name的時候,另一個不會發(fā)生改變疹启。

person1.name = "jing";
console.log(person1.name);  //jing
console.log(person2.name);  //meng

每個實(shí)例對象都有自己的屬性和方法的副本古程,改變其中的一個并不會影響另一個,這就造成了資源和空間的浪費(fèi)喊崖,也無法實(shí)現(xiàn)數(shù)據(jù)的共享挣磨。

為了解決上面的問題,作者Brendan Eich決定使用構(gòu)造函數(shù)設(shè)置一個prototype屬性茁裙,可以讓所有對象實(shí)例共享它所包含的屬性和方法廊宪。

上面的例子可以寫成:

function Person(age) {
  this.age = age;
}
Person.prototype.name = "meng";

var person1 = new Person(12);
var person2 = new Person(13);
Person.prototype.name = "jing";
console.log(person1.name);  //jing
console.log(person2.name);  //jing

這時person1和person2就共享了Person.prototype.name這個屬性傅寡,只要其中一個改變扭倾,就會同時影響兩個實(shí)例對象模聋。

原型是什么

只要創(chuàng)建了一個新函數(shù)灶搜,就會根據(jù)一組特定的規(guī)則為該函數(shù)創(chuàng)建一個prototype屬性,這個屬性指向函數(shù)的原型對象。所有原型對象都會獲得一個指向prototype對象的constructor屬性。如圖:

14805248662081.jpg

拿上面的例子來說瑰艘,Person.prototype.constructor又指向了Person萨赁。

proto紫皇、prototype和constructor

每一個生成的對象都有一個__proto__屬性萄窜,當(dāng)調(diào)用構(gòu)造函數(shù)創(chuàng)建一個新的實(shí)例之后,__proto__就指向了構(gòu)造函數(shù)的原型對象佃延,即構(gòu)造函數(shù)的prototype屬性榆浓。

下圖所示:當(dāng)定義person1是一個數(shù)組時萍鲸,person1自帶一個__proto__屬性嘿期。

14805256492639.jpg

下圖所示:當(dāng)定義Person構(gòu)造函數(shù)時秀菱,Person自帶一個prototype屬性。prototype屬性自帶一個constructor屬性循捺,至于其他的屬性叉谜,都是從Object繼承而來的董栽。

14805260237657.jpg

下圖所示:當(dāng)new一個實(shí)例對象person1時补疑,_proto_就指向了構(gòu)造函數(shù)Person的原型對象厢钧,即構(gòu)造函數(shù)的prototype屬性∮┎剩可以對比一個person1的_proto_屬性在實(shí)例化之前和之后的變化肆汹。

14805259038416.jpg

下圖是展示了Person構(gòu)造函數(shù)浪册、Person的原型屬性以及Person現(xiàn)有的兩個實(shí)例之間的關(guān)系厚者。


14805245325304.jpg

new運(yùn)算符的工作原理

new 運(yùn)算符接受一個函數(shù)F及其參數(shù):new F(arguments...)梧却。這一過程分為三步:

創(chuàng)建類的實(shí)例祖秒。這步是把一個空的對象的__proto__屬性設(shè)置為 F.prototype抬纸。
初始化實(shí)例咙俩。函數(shù)F被傳入?yún)?shù)并調(diào)用,關(guān)鍵字this被設(shè)定為該實(shí)例湿故。
返回實(shí)例阿趁。
現(xiàn)在我們知道了new是怎么工作的,我們可以用JS代碼實(shí)現(xiàn)一下:

function New (f) {
    var n = { '__proto__': f.prototype }; /*第一步*/
    return function () {
        f.apply(n, arguments);            /*第二步*/
        return n;                         /*第三步*/
    };
}

hasOwnProperty函數(shù)

hasOwnProperty用來判斷該屬性屬于實(shí)例自定義的屬性而不是原型鏈上的屬性晓锻。

function Person(age) {
  this.age = age;
}
Person.prototype.name = "meng";

var person1 = new Person(12);
person1.hasOwnProperty('age');  //true
person1.hasOwnProperty('name'); //false

JavaScript引擎如何來查找屬性

以下代碼展示了JS引擎如何查找屬性:

function getProperty(obj, prop) {
    if (obj.hasOwnProperty(prop))
        return obj[prop]

    else if (obj.__proto__ !== null)
        return getProperty(obj.__proto__, prop)

    else
        return undefined
}

通過上面的代碼可以看出來歌焦,js先查找自身有沒有該屬性,如果沒有的話砚哆,就查找proto屬性指向的原型對象中有沒有独撇,如果沒有的話,就去查它的原型的原型中有沒有,一直到原型鏈的最頂端為止躁锁。

參考:
阮一峰:Javascript繼承機(jī)制的設(shè)計(jì)思想
JavaScript的原型機(jī)制

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末纷铣,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子战转,更是在濱河造成了極大的恐慌搜立,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件槐秧,死亡現(xiàn)場離奇詭異啄踊,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)刁标,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門颠通,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人膀懈,你說我怎么就攤上這事顿锰。” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵硼控,是天一觀的道長刘陶。 經(jīng)常有香客問我,道長牢撼,這世上最難降的妖魔是什么匙隔? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮浪默,結(jié)果婚禮上牡直,老公的妹妹穿的比我還像新娘。我一直安慰自己纳决,他們只是感情好碰逸,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著阔加,像睡著了一般饵史。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上胜榔,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天胳喷,我揣著相機(jī)與錄音,去河邊找鬼夭织。 笑死吭露,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的尊惰。 我是一名探鬼主播讲竿,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼弄屡!你這毒婦竟也來了题禀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤膀捷,失蹤者是張志新(化名)和其女友劉穎迈嘹,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體全庸,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡秀仲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了壶笼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片啄育。...
    茶點(diǎn)故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖拌消,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤墩崩,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布氓英,位于F島的核電站,受9級特大地震影響鹦筹,放射性物質(zhì)發(fā)生泄漏铝阐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一铐拐、第九天 我趴在偏房一處隱蔽的房頂上張望徘键。 院中可真熱鬧,春花似錦遍蟋、人聲如沸吹害。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽它呀。三九已至,卻和暖如春棒厘,著一層夾襖步出監(jiān)牢的瞬間纵穿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工奢人, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谓媒,地道東北人。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓何乎,卻偏偏與公主長得像句惯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子宪赶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容