-1

I would like an insight about my codes, what is going on behind the scene? I am new about JS Object prototype, i use to manipulate object but no really playing with prototype!

I have two scripts (JavaScript) as shown below:

// First script //
function MyObject(dim=3){
  this.table= [];// 2D array
  this.initialiseTable(dim);
  this.setTable = function (index,symbol){
    // i want to change only one element of my table
    this.table[index[0]][index[1]]=symbol;
  };
}

MyObject.prototype ={
  initialiseTable:function(dim){
    var array = []; 
    for (let i=0; i<dim; i++){
      array.push("0");
    }
    for (let i=0; i<dim; i++){
      this.table.push(array);
    }

  }
};

console.log("First script")


var O = new MyObject(6);
console.log(O.table);
O.setTable([1,3],"Changed");
console.log(O.table);


// Second script 

// First script //
function MyNewObject(dim=3){
  this.table= [];// 2D array
  this.initialiseTable(dim);
  this.setTable = function (index,symbol){
    // i want to change only one element on my table
    this.table[index[0]][index[1]]=symbol;
  };
}

MyNewObject.prototype ={
  initialiseTable:function(dim){
    // i delete the array variable and implement something hard but then 
    // i don't have the flexibility to set  freely the table dimension 
    for (let i=0; i<dim; i++){
      this.table.push([0,0,0,0,0]);
    }

  }
};
console.log(" ");
console.log("Second script");
var OO = new MyNewObject(6);
console.log(OO.table);
OO.setTable([1,3],"Changed");
console.log(OO.table);

The difference between both codes is only in seTable definition. Now here is the table after setTable call on the O object (first script):

[ [ '0', '0', '0', 'Changed', '0', '0' ],
  [ '0', '0', '0', 'Changed', '0', '0' ],
  [ '0', '0', '0', 'Changed', '0', '0' ],
  [ '0', '0', '0', 'Changed', '0', '0' ],
  [ '0', '0', '0', 'Changed', '0', '0' ],
  [ '0', '0', '0', 'Changed', '0', '0' ] ]

and here is the table after setTable call on the OO object:

[ [ 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 'Changed', 0, 0 ],
  [ 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0 ],
  [ 0, 0, 0, 0, 0, 0 ] ]

Why I get all the third element of each row change in the object table with the first script?

KKoku
  • 31
  • 1
  • 9
  • 1
    setTable code is different in the firstScript and secondScript, that is making the difference – Geeky Dec 07 '16 at 19:57
  • 2
    The difference is that in the first function, every array you add to your table is actually _the same object_. Modify any value in there, and it will be modified everywhere. This is because you create a new Array using `var array = []; ` and then inserting it everywhere, while the second creates a fresh new array filled with zeroes for every push, – somethinghere Dec 07 '16 at 19:59
  • I don't see what this has to do with the prototype? – Bergi Dec 07 '16 at 20:02
  • You are feeding your table six copies of the same array. – Tim Consolazio Dec 07 '16 at 20:07
  • https://stackoverflow.com/questions/9489200/unexpected-output-in-javascript-2d-array-population/, https://stackoverflow.com/questions/966225/how-can-i-create-a-two-dimensional-array-in-javascript – Bergi Dec 07 '16 at 20:09
  • Thank you all for your quick replies and explanations!! I got 50 push ups :) – KKoku Dec 07 '16 at 20:28

2 Answers2

0

It is the difference between creating one object and assigning it everywehere versus creating a new object for every assignment. This:

var array = [];
for (let i=0; i<dim; i++){
    this.table.push(array); // Assign pre-created array
}

will create one array and assign it to every value in your table. This however:

for (let i=0; i<dim; i++){
    this.table.push([]); // Create fresh array (`[]`) and assign
}

You could test this by seeing if the arrays are the same object:

table[0] === table[1] // true in the first example, false in the second

Lets test this:

var test1 = [];
var test2 = [];

// Lets quickly fill both
var filler = ['Precreated Array'];
while( test1.length < 3 ) test1.push( filler );
while( test2.length < 3 ) test2.push(['New array (' + test2.length + ')']);

// Now lets see if the entries are similar
test1.forEach(function(arr, i){
  console.log('test1[0] === test1[' + i + '] | true? ', arr === test1[0], 'Same object!')
})
test2.forEach(function(arr, i){
  // The first one will be true, because a duck is a duck.
  console.log('test2[0] === test2[' + i + '] | false? ', arr === test2[0], 'Different object!')
})
somethinghere
  • 16,311
  • 2
  • 28
  • 42
0

You are feeding your table the same array six times.

You need to do something like this:

initialiseTable:function(dim){
    for (let i=0; i<dim; i++){
      var arr = []; // every time, create a new array
      for ( let j = 0; j < dim; j++) {
         arr.push ( '0' ); // the stuff to the new one
      }
      this.table.push(arr); // add to the table
    }
  }

An example of the old "why is my event handler showing the same number in all my list things" problem.

Tim Consolazio
  • 4,802
  • 2
  • 19
  • 28