A. Gille
A. Gille

Reputation: 1048

How to make object in prototypes not shared in javascript

I'm trying to dynamically generate a prototype by adding properties in order to save time. My wish is to generate the prototype only once as the generation process is time consuming, and then use this prototype for another Object.

// Generated prototype
var PROTO = {
    a: "a",
    b: "b",
    data : { // Object dynamically added through time-consuming function
        c: "c",
        d: "d"
    }
}

function OBJ() {}
OBJ.prototype = PROTO;

var obj1 = new OBJ();
var obj2 = new OBJ();

PRINT1();

obj1.a = "non a";
obj1.data.c = "non c";

PRINT2();

At PRINT1 the output is

obj1: (a, b, c, d), obj2: (a, b, c, d)

At PRINT2 the output is

obj1: (non a, b, non c, d), obj2: (a, b, non c, d)

I understand that both obj1 and obj2 shares the same reference to data object, but it's not how prototypes should work in the concept...

I tried also this way, but it didn't work.

function PROTO () { ... }

[...]

OBJ.prototype = new PROTO();

How can I have objects with same internal structure taken from a generated prototype?

Upvotes: 1

Views: 59

Answers (2)

Thomas
Thomas

Reputation: 3593

Well that's exactly how Object-references and Prototypes work.

You can imagine the prototypal inheritance like the object being a proxy with a fallback to the prototype if the accessed property is not found on the current object.

And every instance refers to the same prototype-object.

So if you access obj.data, you access the data-object on the (one and only) prototype-object and therefore change it for each instance. This can be sometimes what you want, most of the time it is not, but it is consistent to every other object-reference.

But i think you try to fix the wrong problem (XY-Problem). Instead of caring how many nanoseconds you can shape of by using prototypes, you should better inplement pooling, to avoid the task of creation, deletion and Garbage Collection at all.

Upvotes: 1

Bergi
Bergi

Reputation: 664548

You will need to create an own child object for every instance, there's no way around this. When you use Object.create you'll have to do it manually, if you use constructors you can do it there:

function OBJ() {
    this.data = Object.create(PROTO.data);
}
OBJ.prototype = PROTO;

new OBJ().data === new OBJ().data // false

Upvotes: 1

Related Questions