对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"
答案 0 :(得分:2)
===
没有回答两个事物是否相同的问题,而是它们是否是对同一个对象的引用。
x
和Object.prototype
可能具有相同的属性,因此您可以将它们称为等效属性,但它们是两个不同的对象。
如果你这样做
x.foo = 3
它们现在不再等效,因为它们是两个不同的对象。你换了一个而不是另一个。
如果
x === Object.prototype
是真的,然后
x.foo === Object.prototype.foo
无论您分配给x.foo
或Object.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 = ...;
。您只能通过tail
在Circle
实例上定义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" ]