[英]Javascript prototype through Object.create()
var someObj = function() { }
var p = new someObj();
alert(someObj.prototype); // This works
alert(p.prototype); // UNDEFINED, but why?
someObj.prototype.model= "Nissan";
alert(p.model); // This works! I understand the dynamic nature of prototypes, but doesn't that mean that p.prototype === someObj.prototype?
為什么會這樣? 由於“p”是“someObj”的一個實例,為什么原型未定義? 我的意思是,當我向“someObj”原型添加屬性時,它可以被“p”訪問,那么為什么原型不可訪問?
這里重要的是函數對象的prototype
屬性不是對象的原型。 這個對象將被指定為您通過new someObj
創建的對象的原型。 在ES5之前,您無法直接訪問對象的原型; 從ES5開始,您可以通過Object.getPrototypeOf
。
回覆
alert(p.prototype); // UNDEFINED, but why?
原因是p
對象沒有名為“prototype”的屬性。 它有一個底層原型,但這不是你訪問它的方式。
所有函數對象都有一個名為prototype
的屬性,這樣如果它們被用作構造函數,我們就可以定義這些構造函數創建的對象的底層原型的屬性。 這可能有所幫助:
function Foo() {
}
Foo.prototype.answer = 42;
console.log(Foo.prototype.answer); // "42"
var f = new Foo();
console.log(f.answer); // "42"
最后一行是這樣的:
f
對象。 f
有自己的屬性叫做“回答”嗎? f
有原型? 你在問題的標題中提到過Object.create
。 理解Object.create
與構造函數完全分離很重要。 它被添加到語言中,因此如果您不希望使用構造函數,則不必使用,但仍可以在創建該對象時直接設置對象的原型。
那是因為prototype
是構造函數的屬性,而不是它自身的屬性。 但是, prototype
對象具有對構造函數的引用,因此您可以通過其constructor
屬性訪問對象的prototype
:
function Foo() {}
Foo.prototype.foo = "bar";
var c = new Foo;
console.log( c.constructor === Foo ); // true
console.log( c.constructor.prototype ); // { foo: 'bar' }
但是,如果覆蓋構造函數的初始prototype
屬性,這將不起作用:
function Foo() {}
// I overwrite the prototype property, so I lose the initial reference
// to the constructor.
Foo.prototype = {
foo: "bar"
};
var c = new Foo;
console.log( c.constructor === Foo ); // false
console.log( c.constructor === Object ); // true
console.log( c.constructor.prototype ); // {}
這就是為什么你最好使用ES5中引入的新Object.getPrototypeOf
方法。
function Foo() {}
Foo.prototype = {
foo: "bar"
};
var c = new Foo;
console.log( c.constructor === Foo ); // false
console.log( c.constructor === Object ); // true
console.log( c.constructor.prototype ); // {}
console.log( Object.getPrototypeOf(c) ); // { foo: 'bar' }
另一種解決方案是確保恢復原型上的constructor
引用:
function Foo() {}
// Overwriting the initial prototype
Foo.prototype = {
constructor: Foo, // restore the constructor reference
foo: "bar"
};
p.prototype不起作用,因為在這種情況下p = someObj.prototype。
基本上當你使用new運算符時,發生的是構造函數someObj用於初始化一個新對象。 這意味着它返回一個對象,該對象具有構造函數原型的屬性和方法。
因此p = someObj.prototype和p.prototype是未定義的,因為p不是構造函數。
本文可能有助於解釋這一點
p
是someObj
一個實例 。 原型屬於構造函數。 您可以使用p.constructor.prototype
檢索p
的構造函數原型
在Javascript,構造函數中,實際上所有函數都獲得了一個prototype屬性。 對象(即一組鍵值對)沒有prototype屬性。 在上面的例子中,
var someObj = function() { } // this is a function, so it has a prototype property
var p = new someObj(); // this is an instance object, so it doesn't
這就是為什么someObj.prototype被定義,但p.prototype不是。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.