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ます。各関数(ゲッター)には参照がpropあるため、後で呼び出されたとき(ゲッターが使用されたとき)はprop、ループで割り当てられた最後の値である値を使用します。

つまり、getterは後で呼び出されるため、の値propは最後に設定された値になります。defineProperty一方、クロージャがないため、正しい値を取得します。ループが完了した後ではなく、呼び出し時の値で呼び出されます。

于 2012-12-09T13:33:43.130 に答える