使用字符串作为键设置对象的值
Set value of object using a string as the key
假设我有一个表示对象中键的字符串。这里有一个例子:
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;
}
编辑:以前的版本不适用于"无点"键。。。固定的
在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中是通过引用传递的。
您可以使用一对函数来设置和获取值。我只是举了一个例子。
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 }
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);
我认为这是一个重要的问题,我需要一个变体,它允许在对象中嵌套数组,并用于深度创建不存在的字段。我知道你指定了"对象",但实际上对象也可以包含数组。在这种情况下,@Marshall的优秀代码并没有帮助我。所以我开始摆弄,得到了以下代码(希望这能帮助到任何人):
function objGet(obj, keyString) {
// allow for arrays, returns undefined for non-existant-fields.
var keys=[{label:"",type:"field",is_array:false}], current_key=0;
for(var i=0;i<keyString.length;i++)
{
var c=keyString.charAt(i);
switch(c)
{
case ".":
current_key++;
keys[current_key]={label:"",type:"field",is_array:false};
break;
case "[":
keys[current_key].is_array=true;
current_key++;
keys[current_key]={label:"",type:"index",is_array:false};
break;
case "]":
break;
default:
keys[current_key].label+=c;
}
}
var part=obj;
for(i = 0; i < keys.length; i++)
{
var label=keys[i].label;
if(i==keys.length-1)
{
return part[label];
}else{
if(part[label] === undefined)
{
return undefined;
}
part = part[label];
}
}
}
function objSet(obj, keyString, val) {
// allows for arrays, deep creates non-existant fields.
var keys=[{label:"",type:"field",is_array:false}], current_key=0;
for(var i=0;i<keyString.length;i++)
{
var c=keyString.charAt(i);
switch(c)
{
case ".":
current_key++;
keys[current_key]={label:"",type:"field",is_array:false};
break;
case "[":
keys[current_key].is_array=true;
current_key++;
keys[current_key]={label:"",type:"index",is_array:false};
break;
case "]":
break;
default:
keys[current_key].label+=c;
}
}
var part=obj;
for(i = 0; i < keys.length; i++)
{
var label=keys[i].label;
if(i==keys.length-1)
{
part[label] = val;
}else{
if(part[label] === undefined)
{
// we need to create it for deep set!
if(keys[i].is_array)
{
part[label]=[];
}else{
part[label]={};
}
}
part = part[label];
}
}
}
// TESTS
var obj = {
test: 12,
high: {
sky: {
val: 14
}
},
kneedeep: [
{something:"som0",something_else:"elze0"},
{something:"som1",something_else:"elze1"}
],
low: [1, 2, 3]
};
var obj_str=JSON.stringify(obj);
console.log("testing with object: "+obj_str);
// TEST GET
console.log("test: "+objGet(obj, 'test')); // returns 999
console.log("high.sky.non.existant: "+objGet(obj, 'high.sky.non.existant')); // returns undefined
console.log("kneedeep[0].something: "+objGet(obj, 'kneedeep[0].something')); // returns "som0"
console.log("kneedeep[1].something_else: "+objGet(obj, 'kneedeep[1].something_else')); // returns "elze1"
console.log("high.sky.val: "+objGet(obj, 'high.sky.val')); // returns 14
console.log("low[0]: "+objGet(obj, 'low[0]')); // returns 1
// TEST SET
objSet(obj, 'test', 999); // return 999
console.log("result SET 'test', 999:");
console.log(JSON.stringify(obj));
obj=JSON.parse(obj_str); // reset the object
objSet(obj, 'high.sky.non.existant', 1234); // creates the necessary objects.
console.log("result SET 'high.sky.non.existant', 1234:");
console.log(JSON.stringify(obj));
obj=JSON.parse(obj_str); // reset the object
objSet(obj, 'high.sky.val', 111);
console.log("result SET 'high.sky.val', 111:");
console.log(JSON.stringify(obj));
obj=JSON.parse(obj_str); // reset the object
objSet(obj, 'kneedeep[0].something', 111);
console.log("result SET 'kneedeep[0].something', 111:");
console.log(JSON.stringify(obj));
obj=JSON.parse(obj_str); // reset the object
objSet(obj, 'kneedeep[1].something_else', 1234);
console.log("result SET 'kneedeep[1].something_else', 1234:");
console.log(JSON.stringify(obj));
相关文章:
- 设置对象中元素的样式
- 使用AJAX设置对象属性
- 如何在使用javascript加载页面时直接设置对象参数
- 设置对象文字数组以将值传递给服务器
- 在 javascript 中使用它获取未定义的设置对象的属性值
- 有没有一种快捷方式可以让我用javascript或jQuery设置对象的字段
- three.js CanvasRenderer-设置对象的初始颜色和透明度纹理
- Javascript设置对象选项
- 如何设置对象沿世界x轴旋转90度
- 设置对象'的财产
- 从方法内部设置对象变量
- 如何在应用程序时设置对象值是午餐
- 通过过滤器数组设置对象数组的属性
- Three.js设置对象不透明度/透明度
- 下划线/洛达什号中的快捷方式,用于(递归)设置对象的所有属性
- 重新设置对象的格式
- 为什么要使用 $.data() 而不是直接通过 JavaScript 设置对象
- 动态设置对象文本值
- 使用 D3.csv 设置对象的数据属性
- 设置对象数据结构数组属性