2013-11-28 85 views
8

考慮以下幾點:「原型」的反義詞是什麼?

var o = {foo: 'bar'}; 
var p = Object.create(o); 

如果o原型p,那麼什麼是p關於o

+2

@yuan我最初達成的措辭,但原型*不是*「構造函數」。就是說,'p instanceof o'會拋出一個TypeError。 – user2864740

+1

確實。 'p instanceof o'是一個'TypeError'。 – Amadan

+0

@Amadan,但這並沒有任何意義。這實際上是什麼意思,是不是? – user3025492

回答

5

我不知道,有關於它的原型是另一個對象的對象的正式用語任何廣泛的共識,但恕我直言術語派生對象是可以接受的。

原型繼承的要點是一個對象從另一個繼承,或者從另一個繼承。在一些經典的OO語言中,比如C++,你會聽到派生類,因爲類繼承自其他類。因爲繼承是在原型語言中的對象之間,所以我會說「派生對象」是有道理的。

+1

我不會使用術語派生對象的原因在我的答案闡述的原因。 –

+0

@ErikReppen我對你的回答滿意,但我在這裏的答案是要獨立於JS(不考慮構造函數)。當一個對象是從一個原型「創建」的時候,它就是一種推導:你從一個原型圈中取出一個圓。在JS中它是真實的,它對每個函數都有一個原型屬性,用於使用函數創建的對象的原型,您可以動態地改變「類型」的性質。我相信在JavaScript中,'new'優於'Object.create'。儘管如此,'Object.create'確實會說「讓我成爲一個新的對象,像現有的對象」 –

+0

我不熟悉JS以外的原型,但我認爲這是一個公平的點,在屬性克隆而不是通過引用現有對象的調用對象附加。 –

0

p將成爲o和o的原型鏈,將成爲p的原型鏈。當某個成員不能直接在實例上找到時,使用原型鏈。 JavaScript的看起來最多隻能原型鏈,直到它找到的成員或返回undefined:https://stackoverflow.com/a/16063711/1641941

var o = {o:22} 
var p = Object.create(o); 
p.p = 33; 
var q = Object.create(p); 
console.log(q); 
console.log(q.__proto__); 
console.log(q.__proto__.__proto__); 
+0

我在問關於命名法。 – user3025492

+0

@ user3025492不確定使用派生是否是一個好的術語。它讓你思考基於課程的術語。但我想你可以稱它爲任何你想要的東西,因爲大多數JS程序員都不知道它是否存在:無論如何,https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain – HMR

3

注:在現實中每個對象的原型實際上有構造參考。所以這是錯誤的,儘管關於非直接關係的觀點是成立的。原型對象仍然可以被換出,但原型實際上已連接到對象,並且可以直接使用__proto__Object.getPrototypeOf(instance)原型不是標準的,所以Object.getPrototypeOf更爲理想(如果可用))訪問。

我認爲最好從一個對象的構造函數的角度來考慮原型。所以

function objCreate(prototypeObject){ 
    var constructor = function(){}; 
    constructor.prototype = prototypeObject; 

    return new constructor; 
} 

的情況下:的Object.create看作看起來像這樣的功能

var o = {foo: 'bar'}; 
var p = objCreate(o); 

0被賦值給p的構造函數的原型屬性。

現在檢查了這一點:

alert(p.foo);//'bar' 

p.constructor.prototype = { foo: 'foobiedoobie', bar: 'ubarfu' } 
alert(p.foo);//'foobiedoobie' // and we could access bar if we wanted to 

使用「衍生」一詞,或其他任何的斷言的兩種munges什麼實際發生的事情之間有直接的關係,因爲你可以換出的原型屬性p的構造函數,可以追溯地更改p的所有構造函數實例的所有屬性。 p不是從o派生的。 o直到我們改變它爲止,如果你調用一個p沒有的屬性,它的屬性將被檢查。然後,如果該備份對象沒有它,則JS調用對象會檢查其構造函數的原型等等。

這就是爲什麼我個人不喜歡Object.create或新的即將到來的類語法。這一切都是一樣的,但是我們爲了一個非常小的語法糖的勝利而埋沒了實際上正在發生的事情,這使得我們可以很容易地生成語法的語法水域變得更加混亂。

那麼,關於o的p是什麼?

p是一個構造函數的實例,此時恰好有o作爲它的 原型。

這裏沒有直接的關係。試圖斷言一個只會混淆人們,他們會錯過真正有效的方式。你不能用大多數語言換出一個類,並且所有新的繼承屬性突然被調用。你可以在JS中。這是因爲它更像是一個備份對象鏈,用於檢查不是直接在實例上設置的屬性,而是繼承方案。

+0

Object.create實際上當你放棄古典繼承方法時,事情變得更加清晰。如果你的對象需要一個構造函數,添加一個「create」方法,該方法執行Object.create(this)並初始化。不需要將原型附加到構造函數上。 –

+0

或者你可以創建一個方法來完成Object.create所做的事情:)。儘管如此,我並不是一個真正的仇敵。我寧願將努力付諸東流,讓保守派編纂者痞子遠離運營商超載等等。 –

相關問題