原型中定义的值是否共享?

时间:2014-03-07 16:44:04

标签: javascript

如果在原型中定义成员在对象的所有实例中共享成员,那么更改该成员的值是否也会为所有对象更改它?

var A = function() {};
A.prototype.value = 1;
A.prototype.getValue = function() {
  return this.value;
};

var B = function() {};
B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;

var a = new A();
document.writeln("a constructor is A = " + (a.constructor === A) + "<br>");
document.writeln("a.value = " + a.value + "<br>");
document.writeln("a.getValue() = " + a.getValue() + "<br>");
a.value += 1;
document.writeln("a.value = " + a.value + "<br>");
document.writeln("a.getValue() = " + a.getValue() + "<br>");

var b = new B();
document.writeln("b constructor is B = " + (b.constructor === B) + "<br>");
document.writeln("b.value = " + b.value + "<br>");
document.writeln("b.getValue() = " + b.getValue() + "<br>");
b.value += 1;
document.writeln("b.value = " + b.value + "<br>");
document.writeln("b.getValue() = " + b.getValue() + "<br>");

var bb = new B();
document.writeln("bb constructor is B = " + (bb.constructor === B) + "<br>");
document.writeln("bb.value = " + bb.value + "<br>");
document.writeln("bb.getValue() = " + bb.getValue() + "<br>");
bb.value += 1;
document.writeln("bb.value = " + bb.value + "<br>");
document.writeln("bb.getValue() = " + bb.getValue() + "<br>");

我得到的结果是:

a constructor is A = true
a.value = 1
a.getValue() = 1
a.value = 2
a.getValue() = 2

b constructor is B = true
b.value = 1
b.getValue() = 1
b.value = 2
b.getValue() = 2

bb constructor is B = true
bb.value = 1
bb.getValue() = 1
bb.value = 2
bb.getValue() = 2

这是我用来试验这个的插件。 http://plnkr.co/edit/znckausaYi9cQ2glJg1A

如果原型中有值,为什么b和bb似乎有单独的值实例?我期望bb的结果看起来像这样:

bb constructor is B = true
bb.value = 2
bb.getValue() = 2
bb.value = 3
bb.getValue() = 3

问题:

  • 为什么这样做?
  • 有没有办法验证原型成员的位置?
  • 我是否可以使用一种工具来证明成员是跨实例共享的,而不是每个实例的成员共享?

3 个答案:

答案 0 :(得分:1)

获取值将返回链中最接近的值。设置值会将其设置在当前对象上,并忽略原型链。

答案 1 :(得分:0)

a.value不是对A.prototype.value的引用。

你也可以这样做:

a.getValue = function () { return 2; }

这不会更改getValue的其他实例的A函数,甚至也不会更改A定义的原型的class A { var value = 1; function getValue() { return this.value; } } var a = new A(); a.value += 1; 函数。


您所做的与以下内容类似:

A.value += 1; // note this can not be done in any classical language that I know

我认为你对此感到困惑:

A.prototype.value += 1;

在JS中你会这样做:

a

这不会影响A,只会在此之后创建{{1}}的新实例。

答案 2 :(得分:0)

使用new创建对象时,会创建一个与先前创建的对象无关的新实例。它们只共享相同的构造函数。

var A = function() {};
A.prototype.value = "a value";


var B = function() {};
B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;

var a = new A();
var b = new B();

console.log(a.value); // a value
console.log(b.value); // a value

a.value = "new a value";

console.log(a.value); // a new value
console.log(b.value); // a value

b.value = "new b value";

console.log(a.value); // new a value
console.log(b.value); // new b value