5

好的,我尝试以这种方式创建新对象:

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;
        }
    })
}

并得到一个不好的结果:

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

我知道创建此对象的其他方法,例如:

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

或者:

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

但是我不明白为什么在第一种方法中,字符串参数“prop”会通过链接发送到函数“defineProperty”。请帮助我理解这一点。抱歉英语不好。

4

1 回答 1

4

当您在循环中创建函数时,您会围绕该循环中使用的变量创建一个闭包。在这种情况下, 周围有一个闭包prop。每个函数(getter)都有一个引用,prop因此当稍后调用它们时(使用 getter 时),它们使用的值prop恰好是循环中分配的最后一个值。

换句话说,由于 getter 是稍后调用的,所以 in 的值prop是它最后设置的任何值。defineProperty另一方面,由于没有闭包,因此获得了正确的值。它在调用时使用值调用,而不是在循环完成后调用。

于 2012-12-09T13:33:43.130 回答