我有一个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.setting1
和myObj.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
})
答案 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没有块范围)。
要解决这个问题,您需要将每个迭代包装在一个单独的函数中。