Object.defineProperty get / set closure

Ok, I'm trying to create a 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, since:

 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 the string parameter "prop" will be sent by the function "defineProperty" by reference. Help me understand this. Sorry for the bad english.

+4
javascript object set get
Dec 09 '12 at 13:08
source share
1 answer

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

In other words, since getter is called later, the value in prop is any value that was set last. defineProperty , on the other hand, gets the correct value since there is no closure. It is called with a value during a call, and not after the loop ends.

+4
Dec 09 '12 at 13:33
source share



All Articles