首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >object.defineProperty在环

object.defineProperty在环
EN

Stack Overflow用户
提问于 2014-04-26 08:21:36
回答 4查看 1.9K关注 0票数 1

目前,我正在使用以下代码为类定义getter和setter:

代码语言:javascript
复制
    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);}
    })

我想我可以把这段代码优化成这样:

代码语言:javascript
复制
    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);}
        });
    }

但这不管用!我没有控制台错误,只是不能设置属性.???

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-04-26 08:55:51

另外两个答案工作得很好(我对它们投了赞成票),但我想补充一点,这是数组迭代器方法派上用场的地方,因为使用它的任务为您的操作创建了一个函数闭包,它自动地解决了这个索引问题:

代码语言:javascript
复制
['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,这种设计模式被一个流行的第三方库所使用,因为它是一种非常紧凑的方式,可以通过几个不同的值运行相同的代码。

票数 4
EN

Stack Overflow用户

发布于 2014-04-26 08:24:12

当循环结束时,i变量将等于fields.length,稍后调用的set函数将使用此值。

尝试使用闭包来捕获当前的索引元素:

代码语言:javascript
复制
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));
}
票数 3
EN

Stack Overflow用户

发布于 2014-04-26 08:25:26

这是典型的闭包问题。您在循环中创建的函数具有对i变量的持久引用,而不是它的副本。因此,当调用访问器函数时,ifields.length,因此从fields[i]获得的值是undefined

通常的解决方案是构建器函数:

代码语言:javascript
复制
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及其objname参数的调用上下文,这些参数不会更改,因此当调用它们时,它们使用正确的name

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23308456

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档