1

I have a simple object with two properties, one string and one array. When I create a few variables, each as a new instance of my object using Object.create, all my variables have their own string properties, but they all share the same array! If you run the code below step by step, you can see at each affectation of the array that all the arrays of the previous variable are also edited !!! (but the string property is ok). Indeed, we can see that the arrays in all the variables are in fact the same array thanks to the ObjectId of the debugger... Do you know how to make each array specific to each variable and not having all the variables sharing the same object?

function myFunction() {
  // Object definition
  var my_object = Object.create(null, {
    my_object_name:  {value: new String(), enumerable: true, writable: true},
    my_object_array: {value: new Array(),  enumerable: true, writable: true},           
    build: {
      value: function (i) {         
        this.my_object_name = "name_" + i.toString();           
        for (var j = 0; j <= 4; j++) {
          this.my_object_array[j] = i + j;
        }
        return this;         
      }
    }
  });

  // Main    
  var my_variable_1 = Object.create(my_object).build(1);
  var my_variable_2 = Object.create(my_object).build(5);
  var my_variable_3 = Object.create(my_object).build(10);
}

At then end, we will obtain the result below, with all different strings for my_object_name property but all the same arrays for the my_object_array property

my_variable_1.name = "name_1" / my_variable_1.array = [10, 11, 12, 13, 14]
my_variable_2.name = "name_2" / my_variable_1.array = [10, 11, 12, 13, 14]
my_variable_3.name = "name_3" / my_variable_1.array = [10, 11, 12, 13, 14]

But I would like to find:

my_variable_1.name = "name_1" / my_variable_1.array = [ 1,  2,  3,  4,  5]
my_variable_2.name = "name_2" / my_variable_1.array = [ 5,  6,  7,  8,  9]
my_variable_3.name = "name_3" / my_variable_1.array = [10, 11, 12, 13, 14]
tehhowch
  • 9,645
  • 4
  • 24
  • 42
Thomas Perrin
  • 675
  • 1
  • 8
  • 24
  • 1
    You don't see the issue with the name property because you assign a new value to the object's property. For the array case, you manipulate a property of the array, rather than assign to the object's property. You should probably invoke a constructor function with `new` if you are attempting to create separate object instances. https://stackoverflow.com/questions/2709612/using-object-create-instead-of-new – tehhowch Mar 06 '19 at 14:57
  • Indeed with new I am ok, thanks! – Thomas Perrin Mar 12 '19 at 10:54

1 Answers1

2

Your my_object_array sits on the prototype and every access leads to same array through prototype chain. Different properties have to sit on the objects themselves. Try this -

// constructor
function MyObject(i) {
  this.name = 'name_' + i; // own
  this.array = this.build(i); // own
}

// on prototype = shared
MyObject.prototype.build = function(i) {
  var arr = [];
  for (var j = 0; j <= 4; j++) {
    arr[j] = i + j;
  }
  return arr;
};

// Main
var my_variable_1 = new MyObject(1);
var my_variable_2 = new MyObject(5);
var my_variable_3 = new MyObject(10);

console.log(my_variable_1.array);
console.log(my_variable_2.array);
console.log(my_variable_3.array);

// [ 1, 2, 3, 4, 5 ]
// [ 5, 6, 7, 8, 9 ]
// [ 10, 11, 12, 13, 14 ]
ra89fi
  • 1,217
  • 1
  • 8
  • 9