2011-10-28 40 views
0

也许愚蠢的问题到JS大师和忍者那里,但这里有:JavaScript:如何访问构造函数的原型?

我对对象的原型对象/属性的理解是,它是一个对象的未来实例的蓝图。鉴于此,对象的新创建的实例不应该与创建它的构造器对象相同吗?

var x = new Object(); 
console.log(x === Object.prototype); // returns false. why?? 

* UPDATE *

所以了解,因为它们是引用不同的东西,这将返回false,我仍然发现新的对象()和Object.prototype包含不同数量的属性。因此,要优化我的问题:如何正确检查原型对象中的属性数量;我如何遍历它们?

我被这个困惑的原因是,如果我创建一个简单的构造函数:

function Circle(){ 
    this.tail = "yes, has tail"; 
} 

,并希望得到它具有属性的数量,做这样的事情:

console.log(Object.getOwnPropertyNames(Circle.prototype)); 
// returns "constructor", I expected it to return "tail" 

回答

2

===不回答两个事物是否相同的问题,但它们是否是对同一个对象的引用。

xObject.prototype在您的示例中可能具有相同的属性,因此您可以称它们等效,但它们是两个不同的对象。

如果你

x.foo = 3 

他们现在已经不再是等同的,因为它们是两个不同的对象。你改变了一个,但没有改变另一个。

如果

x === Object.prototype 

是真实的,那么

x.foo === Object.prototype.foo 

将是相同的,不管你分配给x.fooObject.prototype.foo什么的。

编辑:

function Circle(){ this.tail = "yes, has tail"; } 

console.log(Object.getOwnPropertyNames(Circle.prototype)); 
// returns "constructor", I expected it to return "tail" 

上有Circle.prototype没有tail财产,因为你从未做过Circle.prototype.tail = ...;。您仅在Circle实例上通过this.tail = ...;定义tail

我仍然发现new Object()Object.prototype包含不同数量的属性。

你也在做getOwnPropertyNames自己的属性是那些不是从原型继承的属性,所以通过在x上使用该函数,您明确排除Object.prototype的所有属性。

hasOwnProperty该文档解释“自己的属性”非常好:

这种方法可以被用来确定对象是否具有指定的属性作为该对象的直接属性;与in运算符不同,此方法不检查对象的原型链。

+0

刚更新的问题。获取这部分,但仍然困惑:( – dkugappi

+0

@AlexNabokov,请参阅我的编辑其中的地址编辑。 –

1

console.log(Object.getPrototypeOf(x) === Object.prototype); // true

如果你想获得隐藏属性[[Prototype]]指向原型链中的某个对象的下一个元素只是调用Object.getPrototypeOf

你也错误理解原型链的工作原理。

对于任何给定的对象,如果查找属性,它将首先查看该对象。然后它(递归地)查看对象[[Prototype]]值是否具有该属性。

实施例原型的链:

var o = new Object(); 
// o -> Object.prototype -> null 
var a = new Array(); 
// a -> Array.prototype -> Object.prototype -> null 
var Super = function() {}; 
var Child = function() {}; 
Child.prototype = Object.create(Super.prototype); 
var c = new Child(); 
// c -> Child.prototype -> Super.prototype -> Object.prototype -> null 
0

x为 “对象” 的一个实例。你可能想检查x是否有一个Object作为构造函数。原型不是构造函数。 试试这个

var x = new Object(); 
console.log(x.constructor === Object); 
+0

'.constructor'是一个事实上的标准。有些人忘记使用'.constructor'并且这样的逻辑会中断。 – Raynos

0

关于你提到的更新:

this一个构造函数中与new关键字,而不是prototype创建的实例。

所以,在你的代码片断中......

function Circle(){ 
    this.tail = "yes, has tail"; 
} 

设置this.tail是类似于:

var c = new Circle(); 
c.tail = "yes, has tail"; 

tail只有的实例的属性。

设置tailprototype,你必须使用:

Circle.prototype.tail = "yes, has tail"; 

现在,“自己”的属性是直接设置的实例。这些计数器和覆盖prototype属性同名:

function Circle() { 
    // give the instance its "own" `foo` property 
    this.foo = 'qux'; 
} 

Circle.prototype.foo = 'foo'; 
Circle.prototype.bar = 'bar'; 

var c = new Circle(); 

console.log(c.foo); // the overridden "qux", not the inherited "foo" 
console.log(c.bar); // "bar", as inherited 

// yet the prototype still persists to have its "own" `foo` 
console.log(Circle.prototype.foo); // "foo" 

// While the instance has keys for all involved properties 
console.log(Object.keys(c)); // [ "foo", "bar" ] 

// It also retains which are its "own" 
console.log(Object.getOwnPropertyNames(c)); // [ "foo" ] 
+0

我看到了,谢谢你,我认为当你创建一个构造函数时,原型是任何构造函数定义的副本。 – dkugappi