最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript prototype property not working as expected with array and object fields - Stack Overflow

programmeradmin4浏览0评论

I get an unexpected result with the following code:

var TestModel, u, u2;

function TestModel() {}
TestModel.prototype.a = null;
TestModel.prototype.b = [];

u = new TestModel();
u.a = 1;
u.b.push(1);

u2 = new TestModel();
u2.a = 2;
u2.b.push(2);

console.log(u.a, u.b);     // outputs: 1 [1,2]
console.log(u2.a, u2.b);   // outputs: 2 [1,2]

I find it surprising that u.b and u2.b contain the same values even though each instance of TestModel should have its own instance variables according to how I've setup the prototype. So this is the output I was expecting:

console.log(u.a, u.b);     // expecting: 1 [1]
console.log(u2.a, u2.b);   // expecting: 2 [2]

The same thing happens if I set b to be an object and set keys on it rather than using it as an array. What am I not understanding here?

I get an unexpected result with the following code:

var TestModel, u, u2;

function TestModel() {}
TestModel.prototype.a = null;
TestModel.prototype.b = [];

u = new TestModel();
u.a = 1;
u.b.push(1);

u2 = new TestModel();
u2.a = 2;
u2.b.push(2);

console.log(u.a, u.b);     // outputs: 1 [1,2]
console.log(u2.a, u2.b);   // outputs: 2 [1,2]

I find it surprising that u.b and u2.b contain the same values even though each instance of TestModel should have its own instance variables according to how I've setup the prototype. So this is the output I was expecting:

console.log(u.a, u.b);     // expecting: 1 [1]
console.log(u2.a, u2.b);   // expecting: 2 [2]

The same thing happens if I set b to be an object and set keys on it rather than using it as an array. What am I not understanding here?

Share Improve this question edited Dec 27, 2011 at 14:57 Rob W 349k87 gold badges807 silver badges682 bronze badges asked Nov 22, 2011 at 16:23 hiddentaohiddentao 3912 silver badges8 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 13

There is a difference between assigning values and referencing them.

u.a = 1;

will create a new a property on the object referred to by u. Before the assignment, u.a will refer to TestModel.prototype.a, but assigning a new value actually creates a new property on the actual object:

After the assignment:

On the other hand,

u.b.push(1);

will not create a new property. It will reference the existing property, the array, which is TestModel.prototype.b.

even though each instance of TestModel should have its own instance variables according to how I've setup the prototype

All instances reference the same prototype, hence they reference the same properties the prototype has. You can easily see that because TestMode.prototype === u.b, TestMode.prototype === u2.b and u.b === u2.b all yield true.

It would work if you assign a new value as well to u.b and u2.b as well:

u.b = [];

which is normally done in the constructor:

function TestModel() {
    this.b = [];
}

Prototype properties are exactly the opposite of each instance having their own variables, the point of prototype is that all instances automatically share the same prototype properties, so redefining functions is not required for each instance.

You want each instance to have their own array like this:

function TestModel() {
this.a = null;
this.b = [];
}

The array is in both cases the very same array, namely the one you set to the prototype. This means that both .push calls are acting on that array, so that all of these are [1, 2]:

TestModel.prototype.b
u.b
u2.b

They all refer to the same property.

Prototype is usually used for functions, so that all instances share those same functions. If you are going to modify prototype properties, then they will also be reflected for all instances, which in this case is probably undesirable. If instances should each have a custom array, then also declare a custom one for each instance instead of via prototype.

发布评论

评论列表(0)

  1. 暂无评论