使用字符串作为键的对象设置值
假设我有一个字符串表示对象中的键。这里有一个例子:使用字符串作为键的对象设置值
var obj = {
test: 12,
high: {
sky: {
val: 14
}
},
low: [1, 2, 3]
},
keys = 'high.sky.val';
所以,我想设置的obj.high.sky.val
值(与'high.sky.val'
在一个字符为)。
我知道如何阅读的价值(虽然这未必是最好的方式):
var keyPieces = keys.split('.'), value = obj;
keyPieces.forEach(function(x){
value = value[x];
});
console.log(value); // 14
我无法弄清楚如何设置obj.high.sky.val
(不使用eval
)。
如何设置属性的值,如果该键是一个字符串?
只是为了好玩:
function setKey(key, value, targetObject) {
var keys = key.split('.'), obj = targetObject || window, keyPart;
while ((keyPart = keys.shift()) && keys.length) {
obj = obj[keyPart];
}
obj[keyPart] = value;
}
编辑:以前的版本也不会与 “无点” 键...固定的工作。
function setDeep(el, key, value) {
key = key.split('.');
var i = 0, n = key.length;
for (; i < n-1; ++i) {
el = el[key[i]];
}
return el[key[i]] = value;
}
function getDeep(el, key) {
key = key.split('.');
var i = 0, n = key.length;
for (; i < n; ++i) {
el = el[key[i]];
}
return el;
}
,你可以这样使用它:
setDeep(obj, 'high.sky.val', newValue);
不应该是'el [key [i]]'? – 2012-02-17 22:18:08
根据@ Kolink的回答,您需要在设置时停止在第二个到最后一个属性,这样'el'是一个对象,而不是一个int。另外,获取时,您需要使用'el [key [i]]'。 – 2012-02-17 22:28:11
@火箭,谢谢你的编辑。 – 2012-02-17 23:20:22
其实我不得不做出几个功能GameMaker工作时实现这一目的:HTML5
function js_get(varname) {
if(varname.indexOf(".") < 0)
return window[varname];
else {
var curr = window, steps = varname.split("."), next;
while(next = steps.shift()) curr = curr[next];
return curr;
}
}
function js_set(varname,value) {
if(varname.indexOf(".") < 0)
window[varname] = value;
else {
var curr = window, steps = varname.split("."), next, last = steps.pop();
while(next = steps.shift()) curr = curr[next];
curr[last] = value;
}
}
这工作,因为对象在JS中通过引用传递。
在我的代码中,我尝试了'value = 1000;',它没有更新值。我想我需要停在第二个到最后一个对象,然后设置值。为什么'价值= 1000'工作? – 2012-02-17 22:20:27
这就是这段代码所做的,用'last = steps.pop()'。我只是双重检查它,它确实有效。另一个测试:'a = {b:{c:1}}; d = a.b; d.c = 2;警报(A.B.C); //警报2,而不是1' – 2012-02-17 22:21:46
奇怪。 'a = {b:{c:1}}; d = a.b.c; d = 2;警报(a.b.c);警报1.不知道为什么。我猜是因为'd'被设置为一个值(int),而不是一个对象。这是有道理的。 – 2012-02-17 22:22:52
您可以使用一对函数来设置和获取值。我只是举了一个例子。
objGet
需要一个对象和密钥字符串。它会尝试获得价值。如果它找不到它,它将返回undefined。
objSet
需要一个对象,键字符串和值。它会尝试查找和设置值。如果它不能(因为一个错误的键字符串)它将返回undefined。否则它返回传递的值。
function objGet(obj, keyString) {
for(var keys = keyString.split('.'), i = 0, l = keys.length; i < l; i++) {
obj = obj[keys[i]];
if(obj === undefined) return undefined;
}
return obj;
}
function objSet(obj, keyString, val) {
for(var keys = keyString.split('.'), i = 0, l = keys.length; i < l - 1; i++) {
obj = obj[keys[i]];
if(obj === undefined) return undefined;
}
if(obj[keys[l - 1]] === undefined) return undefined;
obj[keys[l - 1]] = val;
return val;
}
//// TESTING
var obj = {
test: 12,
high: {
sky: {
val: 14
}
},
low: [1, 2, 3]
};
objGet(obj, 'test'); // returns 12
objGet(obj, 'high.sky.val'); // returns 14
objGet(obj, 'high.sky.non.existant'); // returns undefined
objSet(obj, 'test', 999); // return 999
obj.test; // 999
objSet(obj, 'high.sky.non.existant', 1234); // returns undefined
obj.high.sky; // { val: 14 }
objSet(obj, 'high.sky.val', 111); // returns 111
obj.high.sky; // { val: 111 }
很酷,这个工程:-) – 2012-02-17 22:30:31
我如何告诉它什么对象使用? – 2012-02-17 23:08:13
挂起,编辑。我假设你想从全局对象开始解决......现在你去了,现在它可以有一个目标对象(否则它默认为'window')。如果你不想'window'默认,只需删除“|| window”。 – 2012-02-17 23:11:24
@火箭,为简单起见编辑了一下。 – 2012-02-17 23:19:03