JavaScript:如何访问构造函数的原型?

时间:2011-10-28 19:23:25

标签: javascript object constructor prototype-programming

对JS大师和忍者来说可能有些愚蠢的问题但是这里有:

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

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

*更新*

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

我对此感到困惑的原因是,如果我创建一个简单的构造函数:

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

并希望获得它拥有的属性数量,例如:

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

4 个答案:

答案 0 :(得分: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"

tail上没有Circle.prototype属性,因为您从未完成Circle.prototype.tail = ...;。您只能通过tailCircle 实例上定义this.tail = ...;

  

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

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

hasOwnProperty的文档很好地解释了“自己的财产”:

  

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

答案 1 :(得分: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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

关于您的更新:

构造函数中的

this是使用new关键字创建的实例,而不是prototype

所以,就你的片段而言......

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

设置this.tail类似于:

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

tail 实例的属性。

要在tail上设置prototype,您必须使用:

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

现在,“Own”属性是直接在实例上设置的属性。这些计数器和覆盖同名的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" ]