2

How can i execute a function while creating an object using javascript

Running the following code

 var y = [] ;
 var x = [[1,2,3] , [4,5,6] , [7,8,9]]
 for (var i = 0 ; i < 3 ; i++){
     y.push({name :'MyName' , value:function(){return x[i]} }) ; 
 }

 console.log(y) ;  

will generate the following object

{name : 'MyName' , value : function (){return x[i]}

Question

how can i execute this object function having this :

{name : 'MyName' , value : function (){return [1,2,3]}

i tried eval() it didn't work

Here is my jsFiddle

For the people who ask WHY are you doing this ? I'm doing this because object will be copied by value so i will end up having all me object.Value equal to X[2] ;

Mina Gabriel
  • 23,150
  • 26
  • 96
  • 124
  • javascript will maintain that context for you, unless you overwrite `x` – Beat Richartz Feb 11 '13 at 17:12
  • I don't really get it, why would you need a function, why not just `y.push({name :'MyName' , value: x[i] });` ? [Fiddle](http://jsfiddle.net/2Jb9D/1/) – adeneo Feb 11 '13 at 17:17
  • because object copy by value so all the value will be equal to x[2] – Mina Gabriel Feb 11 '13 at 17:19
  • possible duplicate of [Doesn't JavaScript support closures with local variables?](http://stackoverflow.com/questions/643542/doesnt-javascript-support-closures-with-local-variables) – JJJ Feb 11 '13 at 17:22
  • possible duplicate of [Javascript infamous Loop problem?](http://stackoverflow.com/questions/1451009/javascript-infamous-loop-problem) – Bergi Feb 11 '13 at 17:33

2 Answers2

2

Its an odd bit of code. Im not sure what you are trying to achieve. But the problem you are having is that i is being incremented throughout the loop. So when eventually you call the function the value for i is 3 and so beyond the bounds of the x array. You could fix it like this:

var y = [] ;
var x = [[1,2,3] , [4,5,6] , [7,8,9]]
for (var i = 0 ; i < 3 ; i++){
    y.push({
        name :'MyName',
        index: i,
        value:function(){return x[this.index]; } 
    }) ; 
}

console.log(y[0].value()); 

Or if you do not explicitly need a function to execute:

var y = [] ;
var x = [[1,2,3] , [4,5,6] , [7,8,9]]
for (var i = 0 ; i < 3 ; i++){
    y.push({
        name :'MyName',
        value: x[i]
    }) ; 
}

console.log(y[0].value); 
David
  • 8,340
  • 7
  • 49
  • 71
0

To successfully add those objects to the array you need to create a closure over the y.push() statement. The closure will ensure the variable x[i] will be available to the value() function when it is invoked.

The code below defines the 'addItem()' function which closes over the 'value()' function of the object creating a self contained environment. This means the 'value()' function will still have access to the variables defined or passed within the 'addItem()' function even after the 'addItem()' function has finished.

var i = 0
var y = [] ;
var x = [[1,2,3] , [4,5,6] , [7,8,9]];

function addItem(item) {
    y.push({
        name: 'MyName', 
        value: function () {
            return item;
        }
    });
}

for ( ; i < 3 ; i++) {
    addItem(x[i]);
}

console.log(y);
/*
[ { name: 'MyName', value: [Function] },
  { name: 'MyName', value: [Function] },
  { name: 'MyName', value: [Function] } ]
*/
console.log(y[0].value()); // [1, 2, 3]
console.log(y[1].value()); // [4, 5, 6]
console.log(y[2].value()); // [7, 8, 9]

You can also achieve the same thing using an anonymous function within the loop but I choose not to do this as that would have created a new function each time you went around the for loop.