OOP Javascript - isolate an object inside a class

I am trying to create a main object in order to create several instances, each of which inherits children (with unique / isolated properties). However, when I do this, the properties of the object (after changing it) are changed for all created objects. I cannot explain this correctly, but the example should be pretty clear.

Main = function(){}; // Extending the main class with new object. Doing it this way so I can have these in // separate files. Main.prototype.foo = { bar: 1 } // First instance of Main(). var A = new Main(); // Second instance of Main(). var B = new Main(); // Set the bar property to different values for each Main() object. A.foo.bar = 2; B.foo.bar = 3; // Both A.foo.bar and B.foo.bar return 3. alert(A.foo.bar); alert(B.foo.bar); 

What I'm trying to get is to return A.foo.bar 2 and B.foo.bar for return 3, so I have isolated objects that are independent of each other.

Any ideas? Did I just miss something obvious? It would be very grateful!

+6
source share
3 answers

The "foo" property is on the prototype object, and there is only one of them. When you install it through any instance, you affect the same general property.

You can add an instance property to your constructor:

  function Main() { this.instanceProperty = 1; } 

Then it will be per instance.

The prototype is not a โ€œbasic patternโ€ or something like that; this is a real object. It is not copied to instances. Instead, the runtime knows about this, and when references to instance properties that do not actually exist on the instance, it knows to go through the prototype chain and look for properties there.

+5
source

The other answers are more or less correct, but what they lack is the difference between

 Main.prototype.foo = { bar: 1 }; 

and

 Main.prototype.bar = 1; 

In both cases, creating a new Main will create a new instance with a prototype chain with the foo or bar property. In both cases, the instance level property can be overridden without affecting other instances:

 function Main() {}; Main.prototype.foo = { bar: 1 }; Main.prototype.bar = 1; a = new Main(); b = new Main(); a.foo = { bar: 2 }; console.log(a.foo.bar, b.foo.bar); // 2 1 a.bar = 2; console.log(a.bar, b.bar); // 2 1 

But when you create a new Main , the instance variable foo is a reference to a single object {bar:1} , which is common to all instances. Therefore, when you set a.foo.bar , you change the shared object, not the instance variable; the instance variable is a.foo reference.

You do not need to initialize the instance property in the constructor. A standard approach would be to set bar directly on the prototype, i.e. Main.prototype.bar = 1 , which will give you independent instance variables initialized to 1 . However, if you need a more complex data structure (an object, an array, or an instance of another class) for each instance, then you cannot create this as a property on the prototype, because you will be giving each instance a link to a common object, so the path inside the constructor is:

 function Main() { // instance-level object this.foo = { bar: 1 }; } 
+3
source

Since you are editing something on a prototype, it will affect every object.

However, you can do:

 Ax = 2; Bx = 3; 

Then you will have different results.

Or you can have something like this:

 Main = function(val){ this.x = val; } A = new Main(2); B = new Main(3); 
+1
source

Source: https://habr.com/ru/post/890371/


All Articles