在创建对象后更新原型的属性

时间:2013-06-14 08:27:31

标签: javascript

function Foo() {}
Foo.prototype.x = 1

foo = new Foo()
foo2 = new Foo()

foo2.x = 2
Foo.prototype.x = 3

console.log("foo.x = ", foo.x)
console.log("foo2.x = ", foo2.x)
=> foo.x = 3
=> foo2.x = 2

上面创建了两个对象,更新了一个对象的inherited property,然后更新了它们的prototype's property。为什么更新后的对象会保留自己的新值,而另一个跟踪prototype's

@EDIT

上述表达式the inherited property of one object is updated在上述情况下似乎具有误导性。

事实上,即使shadow property已经包含object,当{1}}设置为本地不存在的property时,也会在prototype上创建prototype's properties。在这种情况下,从object的角度来看,local shadow property只是准备就绪。之后,此{{1}}可以直接访问。

4 个答案:

答案 0 :(得分:4)

  

为什么更新的对象会保留自己的新值,但另一个跟踪原型的?

因为x属性直接设置在foo2阴影原型的x属性上。

console.dir(foo2)并亲自看看:

Foo
  x: 2
  __proto__: Foo
     constructor: function Foo() {}
     x: 3
     __proto__: Object

console.dir(foo)显示:

Foo
  __proto__: Foo
     constructor: function Foo() {}
     x: 3
     __proto__: Object

当您尝试访问属性时,将始终返回最接近原型链中对象的值。

可以在§8.12.2 of the ECMAScript 5.1 specification中找到确切的算法。

答案 1 :(得分:1)

如果没有在当前实例上明确定义,JavaScript将只查看原型来解析属性调用。

由于.x被定义为foo2为2,因此它不会再查看该值。 但是,对于foo,.x未在实例上定义,因此它会查看原型,并获得3。

答案 2 :(得分:1)

这是一个很好的问题,无论如何答案很简单:因为foo2对象有一个名为x的属性,它有自己的值并且不是从原型继承的。如果要访问原型值,则应执行foo1.constructor.prototype.x。你必须想象这样的结构:

  • Foo.prototype
    • Foo.prototype.x

变量如下所示:

  • foo = {}
  • foo2 = {x:2}

如果JS在对象中找不到x属性,那么它将查看原型内部。

答案 3 :(得分:0)

您从未设置foo.x,因此默认prototype值取决于.log()3

如果你去

foo.x = 10
foo2.x = 2
Foo.prototype.x = 3

...然后检查foo.x,它是10,因为它已被明确覆盖。

作为必然结果,如果您未设置foo2.x,它也将是3

...
//foo2.x = 2
Foo.prototype.x = 3
... 

如果事情不起作用,那就意味着.prototype属性在实例化后是只读的,所以你有不同版本的默认值,这取决于你实例化的时间和/或改变了财产。没有乐趣。

当您明确覆盖它时,您会知道它何时以及为何被更改。否则,使用当前设置.prototype