Heim > Fragen und Antworten > Hauptteil
function A(params) {
params = params || {};
for(var key in params){
Object.defineProperty(this, key, {
get : function() {
return params[key]
},
enumerable : false
});
}
}
var a = new A({
'x' : 'X',
'y' : 'Y',
'z' : 'Z'
})
console.log(a.x);
Das Ergebnis ist Z, was etwas schwer zu verstehen ist. Das Beispiel für die Konsolenausgabe lautet wie folgt:
滿天的星座2017-05-19 10:42:23
原因其实很简单, 问题就出在for循环里
for(var key in params){
Object.defineProperty(this, key, {
get : function() {
return params[key]
},
enumerable : false
});
}
这里最终key === 'z', 而其他属性的结果都是返回params[key], 也就是params['z']
给我你的怀抱2017-05-19 10:42:23
这就是一个对象复制函数, 唯一和原对象的区别是复制对象a的属性不能使用for循环遍历, 因为闭包的原因get函数调用的key都是z.
a= {
'x' : 'X',
'y' : 'Y',
'z' : 'Z'
}
伊谢尔伦2017-05-19 10:42:23
套个闭包,或者 用 let
function A(params) {
params = params || {};
for(var key in params){
(function(key){
Object.defineProperty(this, key, {
get : function() {
return params[key]
},
enumerable : false
});
}).call(this,key);
}
}
var a = new A({
'x' : 'X',
'y' : 'Y',
'z' : 'Z'
})
console.log(a.x);
或者把 var key 改为 let key
阿神2017-05-19 10:42:23
Object.defineProperty(this, key, {
get : function() {
return params[key]
},
enumerable : false
});
在这里,Object.defineProperty(this, key, {})
这里的key
是立即读取使用的,所以是预期行为x,y,z
get : function() {
return params[key]
}
这个函数是未来的一个时间点执行的,所以运行的时候读取的是最后的key
值,即z
,这个和那道经典的闭包问题一样。
for(var i=0; i<5; i++) {
dom[i].onclick = function() { // dom为一个dom数组
console.log(i)
}
}
打印出来的全是5。