目前,我正在使用以下代码为类定义getter和setter:
Object.defineProperty(FPProject.prototype, 'name', {
get: function() { return this.get('name'); },
set: function(aValue) {return this.set('name', aValue);}
});
Object.defineProperty(FPProject.prototype, 'code', {
get: function() { return this.get('code'); },
set: function(aValue) {return this.set('code', aValue);}
});
Object.defineProperty(FPProject.prototype, 'clientName', {
get: function() { return this.get('clientName'); },
set: function(aValue) {return this.set('clientName', aValue);}
});
Object.defineProperty(FPProject.prototype, 'client', {
get: function() { return this.get('client'); },
set: function(aValue) {return this.set('client', aValue);}
})我想我可以把这段代码优化成这样:
var fields = ['name','code','clientName','client'];
for (var i = 0; i < fields.length; i ++ ) {
Object.defineProperty(FPProject.prototype, fields[i], {
get: function() { return this.get(fields[i]); },
set: function(aValue) {return this.set(fields[i], aValue);}
});
}但这不管用!我没有控制台错误,只是不能设置属性.???
发布于 2014-04-26 08:55:51
另外两个答案工作得很好(我对它们投了赞成票),但我想补充一点,这是数组迭代器方法派上用场的地方,因为使用它的任务为您的操作创建了一个函数闭包,它自动地解决了这个索引问题:
['name','code','clientName','client'].forEach(function(item) {
Object.defineProperty(FPProject.prototype, item, {
get: function() { return this.get(item); },
set: function(aValue) {return this.set(item, aValue);}
});
});当然,您还必须注意.forEach()的浏览器兼容性,它需要IE9或更高版本或更多的填充(如这里所示)。
FYI,这种设计模式被一个流行的第三方库所使用,因为它是一种非常紧凑的方式,可以通过几个不同的值运行相同的代码。
发布于 2014-04-26 08:24:12
当循环结束时,i变量将等于fields.length,稍后调用的set函数将使用此值。
尝试使用闭包来捕获当前的索引元素:
for (var i = 0; i < fields.length; i ++ ) {
(function (index) {
Object.defineProperty(FPProject.prototype, fields[index], {
get: function() { return this.get(fields[index]); },
set: function(aValue) {return this.set(fields[index], aValue);}
});
}(i));
}发布于 2014-04-26 08:25:26
这是典型的闭包问题。您在循环中创建的函数具有对i变量的持久引用,而不是它的副本。因此,当调用访问器函数时,i是fields.length,因此从fields[i]获得的值是undefined。
通常的解决方案是构建器函数:
var fields = ['name','code','clientName','client'];
for (var i = 0; i < fields.length; i ++ ) {
buildProperty(FPProject.prototype, fields[i]);
}
function buildProperty(obj, name) {
Object.defineProperty(obj, name, {
get: function() { return this.get(name); },
set: function(aValue) {return this.set(name, aValue);}
});
}我总是把它变成一个很好的、清晰的、独立的函数,这样A)我们不会在每个循环上重新创建它,而B)它更容易调试、理解和重用。
现在,访问器关闭对buildProperty及其obj和name参数的调用上下文,这些参数不会更改,因此当调用它们时,它们使用正确的name。
https://stackoverflow.com/questions/23308456
复制相似问题