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",那么为什么原型不可访问?
答案 0 :(得分:11)
这里重要的是函数对象的prototype
属性不是对象的原型。这个对象将被指定为您通过new someObj
创建的对象的原型。在ES5之前,您无法直接访问对象的原型;从ES5开始,您可以通过Object.getPrototypeOf
。
RE
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
是否具有名为“answer”的拥有属性?f
有原型吗?您在问题标题中提到了Object.create
。重要的是要理解Object.create
与构造函数完全分开。它被添加到语言中,因此如果您不想使用构造函数,则不必,但仍然可以设置对象的原型 - 直接创建该对象时。
答案 1 :(得分:6)
那是因为prototype
是构造函数的属性,而不是它自身的属性。但是,prototype
对象具有对构造函数的引用,因此您可以通过其prototype
属性访问对象的constructor
:
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"
};
答案 2 :(得分:2)
p.prototype不起作用,因为在这种情况下p = someObj.prototype。
基本上当你使用new运算符时,会发生构造函数someObj用于初始化一个新对象。这意味着它返回一个对象,该对象具有构造函数原型的属性和方法。
因此p = someObj.prototype和p.prototype未定义,因为p不是构造函数。
本文可能有助于解释更多
答案 3 :(得分:1)
p
是someObj
的实例。原型属于构造函数。您可以使用p
p.constructor.prototype
的构造函数原型
答案 4 :(得分:0)
在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不是。