以编程方式在对象构造函数中定义Javascript属性

时间:2013-05-08 16:38:35

标签: javascript

我有一个Javascript构造函数,其中包含一个包含其所有字段的对象,以及对它们进行读/写的函数:

function myObj(){
    var _settingsStore {
        setting1: 1, //default value
        setting2: 2, //default value
    }

    //gets/sets _settingsStore.settingName, does other stuff
    function _genericSet(settingName, settingValue){}
    function _genericGet(settingName){}

我想以编程方式在每个字段周围创建属性:

    for (var _setting in _settingsStore){
        var _str = _setting.toString();
        Object.defineProperties(this, {
            _str: {
                get: function() {return _genericGet(_str)},
                set: function(value) {return _genericSet(_str, value)}
            }
        })
    }

我的意图是_str纯粹是一个变量,应该定义myObj.setting1myObj.setting2。相反,循环尝试两次定义myObj._str

  

未捕获的TypeError:无法重新定义属性:_str

发生了什么事?有没有办法达到我想要的行为?

编辑:为了澄清,这是我实际想要发生的事情,只是在循环之外展开:

Object.defineProperties(this, {
    settings1: {
            get: function() {return _genericGet("settings1")},
            set: function(value) {return _genericSet("settings1", value)}
        },
    settings2: {
            get: function() {return _genericGet("settings2")},
            set: function(value) {return _genericSet("settings2", value)}
        },
        //and so on, if there are more of them
    })

2 个答案:

答案 0 :(得分:3)

我重新开始。如果你只是想使用setter和getter来做一些额外的工作,并且每个对象都将其存储在构造函数中,并且你想重用一些泛型函数,你可以这样做:

function myObj(){
    var _settingsStore = {
        setting1: 1, //default value
        setting2: 2, //default value
    }

    for (var _setting in _settingsStore){
        makeGetSet(this, _setting, _settingStore);
    }
}

function makeGetSet(obj, key, store) {
    Object.defineProperty(obj, key, {
        get: function() { return _genericGet(key, store)}
        set: function(val) {_genericSet(key, val, store)}
    })
}

function _genericGet(key, store){
    var val = store[key];
    // manipulate the val
    return val
}
function _genericSet(key, val, store){
    // manipulate the new val
    store[key] = val
}

我真的不知道你在获取/设置时做了什么样的操作,所以有些可能会缩短。

此外,您可以使_settingsStore通用,并且只需使用变量范围作为值存储,因为无论如何都需要它。

答案 1 :(得分:1)

你误解了对象文字。

{ _str: blah }是一个名为_str的属性的对象;它不使用_str变量的值。

因此,您实际上每次都定义相同的名称 由于您没有设置configurable: true,因此引发了错误。

相反,你应该调用Object.defineProperty(单数),它接受一个字符串后跟一个属性名称 (或者,您可以构建一个对象以传递给defineProperties并使用索引符号为其指定正确的名称)

但是,您的代码仍然无法正常工作,因为所有回调都将关闭同一个变量(Javascript没有块范围)。
要解决这个问题,您需要将每个迭代包装在一个单独的函数中。