0

以下代码取自http://bonsaiden.github.com/JavaScript-Garden/

function Foo() {
    this.value = 42;
}
Foo.prototype = {
    method: function() {}
};

function Bar() {}

// Set Bar's prototype to a new instance of Foo
Bar.prototype = new Foo();
Bar.prototype.foo = 'Hello World';

// Make sure to list Bar as the actual constructor
Bar.prototype.constructor = Bar;

我多次遇到过这种解释“当访问对象的属性时,首先它检查对象自身是否具有该属性,如果没有,则转到该对象的原型以查找该属性等等。”

但是由于以下代码的行为,我很难理解这实际上是有效的

var test1 = new Bar();
var test2 = new Bar();

test1.value = 24;

现在 value 不是 test1 对象的一部分,但它是它的原型的属性,它是一个 Foo 对象,并且由于原型是一个 Foo 对象,所有 Bar 实例都将共享 value 属性,我希望上面的代码做的是将该 value 属性设置为 24,而是为 test1 对象创建一个名为“value”的新属性,并将其分配为 24,将原型中的 value 属性保留为其初始值 42。这听起来不像是共享。test2.value 的值仍然为 42。当我在 firebug 控制台中查看原型链时,它显示 test1 的 value 属性为 24,其原型的 value 属性为 42。

这是非常令人困惑的。有没有人知道它为什么会这样?

4

3 回答 3

2

原型链仅在读取属性时使用,并且仅当在对象本身中找不到该属性时才使用 - 在写入属性值时不使用它。

一旦将属性写入对象 ( test1.value = 24),原型中任何现有的同名“共享”属性都会被隐藏,所有后续读取都将访问现在存储在对象本身中的值。

于 2012-04-12T12:48:47.970 回答
1

我想你想要 .hasOwnProperty()

如果那是您正在寻找的东西,那么其他人已经雄辩地在这里总结了它 hasOwnProperty in javascript

编辑

阅读了另一个答案,然后这次正确阅读了问题......我想收回那个;-)

...

或者也许这就是您正在寻找的东西,您想在做其他事情之前检查属性是否已设置在“哈希”上。

我读了太多次了,我想我会感到困惑,我现在就闭嘴

于 2012-04-12T12:49:36.790 回答
1

只需在末尾附加以下几行即可检查发生了什么。

var test1 = new Bar();
test1.value = 30;

console.log(test1.hasOwnProperty("value"));
console.log(test1.value);

delete test1.value;

console.log(test1.hasOwnProperty("value"));
console.log(test1.value);

输出:

true
30
false
42

条款:

  • hasOwnProperty只返回 true 是 key 是对象的本地属性。
  • delete用于删除不涉及继承属性的本地属性。

解释 如果我们分配一个值,那么它会创建它自己的本地属性并覆盖原型属性。因此,由于本地属性比原型属性具有更高的偏好,因此首先读取它们。

于 2016-04-08T03:44:34.303 回答