考慮從規範中的圖,它下面的代碼,它試圖重現這是怎麼回事:
function CF() {}; // the constructor
CF.P1 = 'foo'; // P1 is an own property of the constructor; P2 is the same
var CFp = { CRP1: 'bar' }; // for now, just an object, with a CRP1 property
CF.prototype = CFp // set CFp as the 'explicit prototype property' of CF;
// only constructors have such a property
var cf1 = new CF(); // an instance;
var cf2 = new CF(); // another instance; cf3..cf5 are constructed the same way
Object.getPrototypeOf(cf1); // CFp; this is the 'implicit prototype link' from cf1 to CFp;
// put another way, CFp became the [[Prototype]] of cf1
你說你被這句話迷惑:命名屬性CFP中的CFP1由cf1,cf2,cf3,cf4和cf5(但不由CF)共享。試想一下:
cf1.CRP1; // 'bar' - found on CFp through cf1
cf2.CRP1; // 'bar' - found on CFp through cf2
CF.CRP1; // undefined
那麼,這句話意味着你可以從cf1..cf5
訪問CRP1
的內容,而不是從構造CF
(記住,函數/構造函數對象也一樣,因此它們可以有屬性)。這是因爲CFp
(CRP1
的「所有者」)不是CF
的[[Prototype]]
,它只是CF.prototype
屬性指向的值。 prototype
屬性只存在於函數對象中,並且僅用於定義調用創建的實例的[[Prototype]]
作爲構造函數調用(如在new CF()
中)。 [[Prototype]]
和prototype
被認爲是「原型」的事實是造成極大困惑的原因 - 也許是令你感到困惑的一部分;希望現在不那麼困惑。考慮到這一點,我會盡量簡短回答你的其他問題。
大部分有關Javascript的文獻指出,函數是第一類對象,因此我希望能夠像對象一樣設置其隱式原型引用以實現原型繼承[...]。
在ES5沒有辦法直接設置隱含原型參考(或[[Prototype]]
)現有的對象,除了非標準__proto__
屬性。你可以做的是創建新的對象與給定[[Prototype]]
。您可以使用var obj = new ConstructorFunction()
來執行此操作,其中[[Prototype]]
的obj
爲ConstructorFunction.prototype
或var obj = Object.create(someOtherObj)
,其中[[Prototype]]
的obj
爲someOtherObj
。該語言的更高版本引入了Object.setPrototypeOf
來做到這一點,但出於性能方面的考慮,它的使用是不鼓勵的。
我可以在函數上設置這個隱式原型,或者它會一直指向Function.prototype(我假設這是默認值)。
是的,用__proto__
或Object.setPrototypeOf
。但通常你不應該。
爲什麼函數有明確的和隱含的原型?在Javascript中,還有其他類型是否有明確的和隱含的原型引用,或者在這方面是函數唯一的嗎?
Function
(下稱「Function
構造函數」)僅僅是一個函數,並作爲任何其它函數它有一個prototype
屬性;它也是一個對象,並且(幾乎)任何其他對象都具有一個對象[[Prototype]]
。還有其他類型的標準構造函數,如Object
,String
,Array
,Boolean
,Number
。它們都是功能,並且有一個prototype
和一個[[Prototype]]
。
好的,我完全重寫了我的答案,試圖專注於我相信你錯過的東西。很難決定什麼可以放棄,但詳細說明一切都需要太多空間和時間。我希望新的答案有幫助! – bfavaretto
@bfavaretto謝謝!現在閱讀,並會留下你的答案的任何反饋。 –