JavaScript(子)对象通过键数组访问

4

是否可以通过一个键数组在对象中设置变量? 例如,我有这个对象:

var obj = {'outer': {'inner': 'value'} };

我想根据一个键的数组设置所选的值:

var keys = ['outer', 'inner'];

为了得到这个结果,将值更改为'newValue'

obj = {'outer': {'inner': 'newValue'} };
2个回答

2
你可以遍历键的数组,确保每个键存在且指向另一个对象,直到到达最后一个键,然后使用它来设置新值。
function setVal(obj, keys, value) {
  var o = obj,
    len = keys.length;

  // iterate through all keys, making sure each key exists and points to an object
  for (var i = 0; i < len - 1; i++) {
    var key = keys[i];

    // check if the current key exists and is an object
    if (obj.hasOwnProperty(key) && typeof obj[key] === 'object' && obj[key]) {
      o = o[key];
    } else {
      // return false or throw an error cause the key is not an object or is missing. 
    }
  }

  // update the value at the last key
  o[keys[len - 1]] = value;
}

这是一个运行的例子:

function setVal(obj, keys, value) {
  var o = obj,
    len = keys.length;
  for (var i = 0; i < len - 1; i++) {
    var key = keys[i];
    if (obj.hasOwnProperty(key) && typeof obj[key] === 'object' && obj[key]) {
      o = o[key];
    } else {
      throw new Error('Key ' + key + ' is not an object or is missing.');
    }
  }
  o[keys[len - 1]] = value;
}

var obj = {
  'outer': {
    'inner': 'value'
  }
};

var validKeys = ['outer', 'inner'];
var invalidKeys = ['outer', 'inner', 'extra'];

console.log('Setting valid keys');
setVal(obj, validKeys, 'new value');
console.log(obj);

console.log('Setting invalid keys');
setVal(obj, invalidKeys, 'new value');
console.log(obj);

如果您希望该方法仅更新现有的键值而不设置新键值,可以使用 hasOwnProperty 将最后一条语句包装在 setVal 中:
// if object already has the last key, update its value
if (o.hasOwnProperty(keys[len - 1])) {
  o[keys[len - 1]] = value;
} else {
  // throw an error or return false since the last key doesn't exist.
}

1
这里的关键点是,可以使用属性名称字符串访问对象属性:obj.propobj["prop"]等效。
function SetValueByKeyNames(obj, keys, value) {
  var target = obj;
  for(var i = 0; i < keys.length - 1; i++) {
    target = target[keys[i]];
    if (!target)
      return false;
  }
  target[keys[keys.length - 1]] = value;
  return true;
}

var obj = {'outer': {'inner': 'value'} };
var keys = ['outer', 'inner'];

console.log(obj.outer.inner); // value
SetValueByKeyNames(obj, keys, 'newValue');
console.log(obj.outer.inner); // newValue

刚看到你比我先完成了,我们有相同的想法 :), +1。 - nem035
来吧,连个模糊的解释都没有吗? - user4639281

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接