开发者

When I add and array to an object using prototype in Javascript, all instances of the object act like they're sharing one array [duplicate]

开发者 https://www.devze.com 2023-04-12 17:07 出处:网络
This question already has answers here: Javascript object members that are prototyped as arrays become shared by all class instances
This question already has answers here: Javascript object members that are prototyped as arrays become shared by all class instances (3 answers) 开发者_运维技巧 Closed 8 years ago.

I'm using a bit of code that I found on the web to manufacture objects. It allows me to organize objects into namespaces, and keeps my code pretty readable.

var TEST = {};

//The next two lines is the stuff that I found on the web. I think I 
//basically understand what's going on here, but maybe I'm implementing it 
//incorrectly?
TEST.testObj = function () { this.initialize.apply(this, arguments); };
TEST.testObj.prototype = {

    a: null,
    b: [],

    initialize: function(a) {

        this.a = a;
        this.b[0] = a;
    }

}


t1 = new TEST.testObj(1);
t2 = new TEST.testObj(2);

alert(t1.a + ', ' + t2.a);
alert(t1.b + ', ' + t2.b);

So, basically t1.a, a primitive, retains it's value when t2 is instantiated. But t1.b changes. It seems like both instances are simply referencing a single array, but creating unique primitives.


If you are fuzzy about prototype inheritance, make sure you read up on it - it will help you reason about this problem. In essence, an object inherits all properties of its prototype, but an object's own properties has higher precedence than those of its prototype. In your example, TEST.testObj.prototype is the prototype of both t1 and t2. Thus, both t1 and t2 inherit its properties.

When the Test.testObj constructor is called, it then calls the initialize method, which then sets the object's a property to the passed-in parameter. This operation will create an a property on the object itself (it's own property), this will override the inherited a property on Test.testObj.prototype. Thus, each time a constructor is called, the new object will get its own a property.

The second statement in initialize

this.b[0] = a;

is different in nature. It first looks up property b on the object. Since it is not found on the object itself, it goes up to its prototype Test.testObject.prototype and finds it there. Now, having a handle on the array object, it then modifies its zeroth element. As you can see, each time the constructor gets called, this same array will be modified.


You're creating this array for the prototype of these.

That's any instance of this prototype shares the same object properties' values.

In order to avoid this situation, you'll design properties/fields in methods if these are constant or shared values. Think about them as static members in other languages.

Otherwise, set properties/fields for the particular instance:

var some = new TEST.testObj();
some.b = []; 

...so b value won't be shared across all testObj instances.

0

精彩评论

暂无评论...
验证码 换一张
取 消