Javascript 學(xué)習(xí)筆記之 對(duì)象篇(二) : 原型對(duì)象
Javascript 是唯一一個(gè)被廣泛運(yùn)用的原型式繼承的語(yǔ)言,所以理解兩種繼承方式的差異是需要時(shí)間的。
第一個(gè)主要差異就是 Javascript 使用原型鏈來(lái)繼承:
function Foo() {
this.value = 42;
}
Foo.prototype = {
method: function() {}
};
function Bar() {}
設(shè)置 Bar 的 prototype 為 Foo 的對(duì)象實(shí)例:
Bar.prototype = new Foo(); Bar.prototype.foo = 'Hello World';
確保 Bar 的構(gòu)造函數(shù)為本身,并新建一個(gè) Bar 對(duì)象實(shí)例:
Bar.prototype.constructor = Bar; var test = new Bar();
下面我們來(lái)看下整個(gè)原型鏈的組成:
test [instance of Bar]
Bar.prototype [instance of Foo]
{ foo: 'Hello World' }
Foo.prototype
{ method: ... }
Object.prototype
{ toString: ... /* etc. */ }
在上面的例子中,對(duì)象 test 將會(huì)同時(shí)繼承 Bar.prototype 和 Foo.prototype。因此它可以訪問(wèn)定義在 Foo 中的函數(shù) method。當(dāng)然,它也可以訪問(wèn)屬性 value。需要提到的是,當(dāng) new Bar() 時(shí)并不會(huì)創(chuàng)建一個(gè)新的 Foo 實(shí)例,而是重用它原型對(duì)象自帶的 Foo 實(shí)例。同樣,所有的 Bar 實(shí)例都共享同一個(gè) value 屬性。我們舉例說(shuō)明:
test1 = new Bar(); test2 = new Bar(); Bar.prototype.value = 41; test1.value //41 test2.value//41
原型鏈查找機(jī)制
當(dāng)訪問(wèn)一個(gè)對(duì)象的屬性時(shí),Javascript 會(huì)從對(duì)象本身開始往上遍歷整個(gè)原型鏈,直到找到對(duì)應(yīng)屬性為止。如果此時(shí)到達(dá)了原型鏈的頂部,也就是上例中的 Object.prototype,仍然未發(fā)現(xiàn)需要查找的屬性,那么 Javascript 就會(huì)返回 undefined 值。
原型對(duì)象的屬性
盡管原型對(duì)象的屬性被 Javascript 用來(lái)構(gòu)建原型鏈,我們?nèi)匀豢梢灾蒂x給它。但是原始值復(fù)制給 prototype 是無(wú)效的,如:
function Foo() {}
Foo.prototype = 1; // no effect
這里講個(gè)本篇的題外話,介紹下什么是原始值:
在 Javascript 中,變量可以存放兩種類型的值,分別是原始值和引用值。
1.原始值(primitive value):
原始值是固定而簡(jiǎn)單的值,是存放在棧 stack 中的簡(jiǎn)單數(shù)據(jù)段,也就是說(shuō),它們的值直接存儲(chǔ)在變量訪問(wèn)的位置。
原始類型有以下五種型: Undefined, Null, Boolean, Number, String。
2.引用值(reference value):
引用值則是比較大的對(duì)象,存放在堆 heap 中的對(duì)象,也就是說(shuō),存儲(chǔ)在變量處的值是一個(gè)指針 pointer,指向存儲(chǔ)對(duì)象的內(nèi)存處。所有引用類型都集成自 Object。
原型鏈性能問(wèn)題
如果需要查找的屬性位于原型鏈的上端,那么查找過(guò)程對(duì)于性能而言無(wú)疑會(huì)帶來(lái)負(fù)面影響。當(dāng)在性能要求必要嚴(yán)格的場(chǎng)景中這將是需要重點(diǎn)考慮得因素。此外,試圖查找一個(gè)不存在屬性時(shí)將會(huì)遍歷整個(gè)原型鏈。
同樣,當(dāng)遍歷一個(gè)對(duì)象的屬性時(shí),所有在原型鏈上的屬性都將被訪問(wèn)。
總結(jié)
理解原型式繼承是寫較為復(fù)雜的 Javascript 代碼的前提,同時(shí)要注意代碼中原型鏈的高度。當(dāng)面臨性能瓶頸時(shí)要學(xué)會(huì)將原型鏈拆分開來(lái)。此外,要將原型對(duì)象 prototype 和原型 __proto__ 區(qū)分開來(lái),這里主要討論原型對(duì)象 prototype 就不闡述關(guān)于原型 __proto__ 的問(wèn)題了,
- 深入理解javascript構(gòu)造函數(shù)和原型對(duì)象
- Javascript中獲取對(duì)象的原型對(duì)象的方法小結(jié)
- js 原型對(duì)象和原型鏈理解
- JS原型對(duì)象通俗"唱法"
- 舉例說(shuō)明JavaScript中的實(shí)例對(duì)象與原型對(duì)象
- 淺談JS原型對(duì)象和原型鏈
- JS原型對(duì)象的創(chuàng)建方法詳解
- js使用原型對(duì)象(prototype)需要注意的地方
- 圖文詳解JavaScript的原型對(duì)象及原型鏈
- JavaScript原型對(duì)象、構(gòu)造函數(shù)和實(shí)例對(duì)象功能與用法詳解
- javascript構(gòu)造函數(shù)以及原型對(duì)象的理解
- JavaScript原型對(duì)象原理與應(yīng)用分析
相關(guān)文章
JavaScript 關(guān)于事件循環(huán)機(jī)制的刨析
js里的事件循環(huán)機(jī)制十分有趣。從很多面試題也可以看出來(lái),考察簡(jiǎn)單的setTimeout也就是考察這個(gè)機(jī)制的,接下來(lái)本文帶你詳細(xì)了解它2021-11-11
js中window.open的參數(shù)及注意注意事項(xiàng)
下面小編就為大家?guī)?lái)一篇js中window.open的參數(shù)及注意注意事項(xiàng)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-07-07
javascript學(xué)習(xí)筆記(四)function函數(shù)部分
本文主要介紹了函數(shù)的調(diào)用方式、返回函數(shù)的函數(shù)、創(chuàng)建匿名函數(shù)、javascript創(chuàng)建動(dòng)態(tài)函數(shù)、回調(diào)函數(shù)、方法和函數(shù)的區(qū)別、js全局函數(shù)、函數(shù)的幾個(gè)作用、prototype屬性、高階函數(shù),非常實(shí)用,有需要的參考下2014-09-09
JavaScript CSS修改學(xué)習(xí)第六章 拖拽
這是一個(gè)簡(jiǎn)單可用的拖拽代碼。用鼠標(biāo)和鍵盤都可以操作。2010-02-02
javascript Function函數(shù)理解與實(shí)戰(zhàn)
小編給大家?guī)?lái)一片關(guān)于javascript的基礎(chǔ)教學(xué)內(nèi)容,關(guān)于Function函數(shù)的訓(xùn)練與理解,一起學(xué)習(xí)下吧。2017-12-12
JS數(shù)學(xué)函數(shù)Exp使用說(shuō)明
JS數(shù)學(xué)函數(shù)Exp使用說(shuō)明2012-08-08

