5

Ok, I try to create new object this way:

var src = {a:'a', b:'b', c:'c'};
var out = {};
for(var prop in src){   
    Object.defineProperty(out, prop,{
        get: function(){
            return src[prop];
        },
        set: function(val){
            src[prop]=val;
        }
    })
}

And get a bad result:

out = {a:'c', b:'c', c:'c'}

I know other ways to create this object, so as:

for (var prop in src) {
    (function(prop) {
        Object.defineProperty(out, prop, {
            get: function() {
                return src[prop];
            },
            set: function(val) {
                src[prop] = val;
            }
        })
    })(prop)
}

or:

Object.keys(src).map(function(prop){
    Object.defineProperty(out, prop,{
        get: function(){
            return src[prop];
        },
        set: function(val){
            src[prop]=val;
        }
    })
})

But I can't understand why, in the first method, a string parameter "prop" will be sent to the function 'defineProperty' by link. Help me to understand this please. Sorry for bad english.

3y3
  • 802
  • 1
  • 6
  • 18
  • for me your other ways don't work either. out always remains an empty object even if I try to assign something like `out.a = "something" ` –  Aug 04 '13 at 11:43
  • 1
    I figured a way to make generic setters/getters. [See my answer here](http://stackoverflow.com/a/18043786/1115652). –  Aug 04 '13 at 14:09

1 Answers1

4

When you create a function inside a loop you create a closure around the variables used in that loop. In this case there is a closure around prop. Each function (the getters) has a reference to prop so when they are called later on (when the getter is used) they use the value in prop which happens to be the last value that was assigned in the loop.

In other words, since the getter is called later, the value in prop is whatever value it was last set to. defineProperty, on the other hand, gets the correct value since there is no closure. It is called with the value at the time of the call rather than after the loop is complete.

Hemlock
  • 6,130
  • 1
  • 27
  • 37