Javascript Prototypes之旅(A Plain English Guide to JavaScript Prototypes译文)
英文原文地址:http://sporto.github.com/blog/2013/02/22/a-plain-english-guide-to-javascript-prototypes/?utm_source=javascriptweekly&utm_medium=email
當(dāng)我第一次學(xué)習(xí)Javascript的對(duì)象模型時(shí),我的反應(yīng)時(shí)困惑。因?yàn)檫@是我第一次接觸基于原型的語言,所以我完完全全被原型弄得糊里糊涂(譯者語:在看這篇文章前,我一直困惑function的prototype和object的__proto__的區(qū)別及它們之間的關(guān)系)。我不能理解JavaScript通過構(gòu)造函數(shù)(function constructors)的方式來實(shí)現(xiàn)一種獨(dú)特的原型。我相信你們當(dāng)中也有類似經(jīng)歷的人。
但隨著自己寫得越來越多javascript,我不僅理解了它的對(duì)象模型而且已經(jīng)開始喜歡上它了。感謝Javascript我發(fā)現(xiàn)基于原型的語言的高雅與靈活。我現(xiàn)在十分喜歡基于原型的語言,因?yàn)樗斜然陬惖恼Z言更簡單和靈活的對(duì)性模型。
1. Prototypes in Javascript
大多數(shù)教程多會(huì)在直接通過講述構(gòu)造函數(shù)(constructor functions)來講解Javascript的對(duì)象。我并不認(rèn)同這種做法,這樣只會(huì)令到我們更困惑。所以下面我們先學(xué)習(xí)一些基礎(chǔ)的原型吧!
2. Prototype chains(prototype inheritance)原型鏈/原型繼承
Javascript的每個(gè)對(duì)象均有一個(gè)原型(prototype)。當(dāng)消息(請(qǐng)求某個(gè)屬性的指令)到達(dá)某個(gè)對(duì)象時(shí),Javascript會(huì)嘗試在該對(duì)象上尋找該屬性,但沒有的時(shí)候就會(huì)將消息轉(zhuǎn)發(fā)到該對(duì)象的原型并在原型上尋找該屬性,就是這樣不斷向上層原型轉(zhuǎn)發(fā)消息,直到在某個(gè)原型中找到該屬性或消息轉(zhuǎn)發(fā)到頂層原型(Object對(duì)象)。(譯者語:每個(gè)對(duì)象的原型均指向另一個(gè)對(duì)象,最頂層的原型就是Object類的實(shí)例)
原型繼承鏈可以無限延長。但一般情況下過長的原型鏈會(huì)令人困惑且難以維護(hù)。
?
3.The __proto__ object
我們可以通過__proto__屬性來簡化對(duì)Javascript原型的理解。但不幸的是__proto__屬性并非Javascript的標(biāo)準(zhǔn)接口。所以我們不應(yīng)該在生產(chǎn)環(huán)境中依賴該屬性。我看一看下面的代碼片段吧!
可以看到通過對(duì)象的__proto__屬性我們可以簡單、方便地設(shè)置對(duì)象的原型。
下面我們通過isPrototypeof函數(shù)來判斷父、子類的關(guān)系
?
4. Prototype lookups are dynamic(原型變化的即時(shí)性)
你可以在任何時(shí)間添加屬性到對(duì)象的原型中,然后就能馬上通過對(duì)象來獲取該屬性。(譯者語:因?yàn)檎?strong>2. Prototype chains(prototype inheritance)原型鏈/原型繼承講述那樣,消息是在原型鏈傳遞并在原型中尋找該屬性,所以為原型增刪改了屬性能即時(shí)反映出來)
?
5. New/updated properties are assigned to the ?object, not to the prototype(增改對(duì)象的屬性)
看代碼吧!
(譯者語:在對(duì)象中已找到了相應(yīng)的屬性,那么就不會(huì)將消息轉(zhuǎn)發(fā)到原型去)
?
6. Object.create
前面已經(jīng)說過__proto__屬性并非設(shè)置原型的標(biāo)準(zhǔn)方法。下面我們使用Object.create方法來創(chuàng)建對(duì)象并指定該對(duì)象的原型。該方法在ES5中可用,但老的瀏覽器和JS引擎要通過es5-hhim來使用了。
(譯者語:我們甚至可以通過object.create(null)開創(chuàng)建一個(gè)沒有原型的對(duì)象;而使用其他方式創(chuàng)建的對(duì)象它的原型鏈中至少有一個(gè)Object類實(shí)例)
當(dāng)然在創(chuàng)建對(duì)象的時(shí)候,還可以設(shè)置該對(duì)象的屬性。
這里打算展開對(duì)象屬性設(shè)置方面的幾個(gè)特性的使用方法,大家可以參考相關(guān)的文檔?here。
7. Object.getProtype
我們可以通過Object.getPrototypeOf來獲取對(duì)象的原型
8.Constructor Functions(構(gòu)造函數(shù))
構(gòu)造函是javascript中用于構(gòu)造原型鏈的最常用的方法。因?yàn)樗菢?gòu)造類型的唯一的原始方式。而很對(duì)javascript引擎對(duì)構(gòu)造函數(shù)也提供了性能上的優(yōu)化。
與此同時(shí),構(gòu)造函數(shù)是javascript中一個(gè)重要且容易令人疑惑的知識(shí)點(diǎn)。
8.1. Functions as contructors
我們通過關(guān)鍵字new來創(chuàng)建Foo函數(shù)的實(shí)例foo
8.2. 'this' is assigned implicitly(隱式分配的this)
當(dāng)我們使用關(guān)鍵字new創(chuàng)建函數(shù)實(shí)例時(shí),Javascript會(huì)隱式地創(chuàng)建一個(gè)this對(duì)象,并在函數(shù)的最后返回該this對(duì)象。
相當(dāng)于
注意:這個(gè)隱式創(chuàng)建的this對(duì)象,當(dāng)且僅當(dāng)使用關(guān)鍵字new創(chuàng)建函數(shù)實(shí)例時(shí)出現(xiàn),若不使用關(guān)鍵字new就會(huì)就會(huì)出現(xiàn)不可預(yù)知的問題,一般情況下為以首字母大寫的方式來命名構(gòu)造函數(shù),以提示需使用關(guān)鍵字new來調(diào)用該函數(shù)。
8.3. The 'function prototype'
每一個(gè)Javascript的函數(shù)都有一個(gè)名為prototype的屬性(譯者語:這個(gè)prototype屬性與之前說__proto__一樣會(huì)指向原型,它們之間的關(guān)系下面的內(nèi)容會(huì)有所講解。因?yàn)閜rototype這個(gè)屬性名稱的中文就是為原型,所以為了區(qū)分下面的內(nèi)容會(huì)用“prototype屬性”來代表function的prototype屬性)
這個(gè)prototype屬性與之前說__proto__一樣會(huì)指向原型,但兩者指向的原型又有所區(qū)別,具體請(qǐng)看
(譯者語:這里原文的代碼和講解有問題,據(jù)本人實(shí)踐所得,對(duì)象并沒有prototype屬性,若要訪問對(duì)象的原型需要使用__proto__屬性或Object.getPrototype函數(shù);而要訪問函數(shù)的原型則要通過訪問prototype屬性。而上述代碼的無論foo是對(duì)象還是函數(shù)均有一方必為undefined,比較結(jié)果鐵定為false。下面代碼片段可以證明兩者指向相同的原型:
function Foo(){}
var foo = new Foo();
Object.getPrototype(foo) === Foo.prototype; // => true
且原型為Foo {},該原型的原型為Object {};Foo{} 中有constructor屬性指向function Foo(){}自身。)
__proto__和prototype屬性的關(guān)系其實(shí)很簡單,prototype屬性所指向的原型會(huì)在使用關(guān)鍵字new調(diào)用構(gòu)造函數(shù)時(shí)被復(fù)制到隱式創(chuàng)建的this對(duì)象的__proto__中。所以prototype屬性指向的原型有那些屬性和方法,那么__proto__就有哪些屬性和方法。
我想大家應(yīng)該已經(jīng)理解了吧,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://www.cnblogs.com/fsjohnhuang/archive/2013/03/04/2942274.html^_^!!
總結(jié)
以上是生活随笔為你收集整理的Javascript Prototypes之旅(A Plain English Guide to JavaScript Prototypes译文)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP正则表达式入门教程[转]
- 下一篇: JavaScript定时调用函数(Set