开发者

Dynamic deep setting for a JavaScript object [duplicate]

This question already has answers here: How to set object property (of object property of..) given its string name in JavaScript? (16 answers) Closed 8 years ago.

Given a string for a object property path, how do I set this property dynamically.

Given this sample object:

var obj = {
    a: {
        b: [ { c: 'Before' } ]
    }
};

It should be able to s开发者_开发技巧et the value with a helper function like this:

setToValue(obj, 'After', 'a.b.0.c');

I tried it with the following code. But parent is a copy if the variable not a reference.

function setToValue(obj, value, path) {
    var arrPath = path.split('.'),
        parent = obj;

    for (var i = 0, max = arrPath.length; i < max; i++) {
        parent = parent[arrPath[i]];
    }

    parent = value;
}


a) What's wrong with a simple a.b[0].c = 'After'?

As for the method:

function setToValue(obj, value, path) {
    var i;
    path = path.split('.');
    for (i = 0; i < path.length - 1; i++)
        obj = obj[path[i]];

    obj[path[i]] = value;
}

Here the JSFiddle: http://jsfiddle.net/QycBz/24/


Here is a full solution.

Also creates objects if they don't exist.

function setValue(obj, path, value) {
  var a = path.split('.')
  var o = obj
  while (a.length - 1) {
    var n = a.shift()
    if (!(n in o)) o[n] = {}
    o = o[n]
  }
  o[a[0]] = value
}

function getValue(obj, path) {
  path = path.replace(/\[(\w+)\]/g, '.$1')
  path = path.replace(/^\./, '')
  var a = path.split('.')
  var o = obj
  while (a.length) {
    var n = a.shift()
    if (!(n in o)) return
    o = o[n]
  }
  return o
}


FWIW, those of you wishing to the same in CoffeeScript might find these methods handy - it's a quite straight port of the above code. As an extra bonus, they make sure all the objects in the path exists (the getPropertyByPath doesn't throw exceptions if they don't, and the set method will create empty objects if any objects in the path happen to be null).

getPropertyByPath: (obj, path) ->
  path = path.split('.')
  parent = obj

  if path.length > 1
    parent = parent[path[i]] for i in [0..path.length - 2]

  parent?[path[path.length - 1]]

setPropertyByPath: (obj, path, value) ->
  path = path.split('.')
  parent = obj

  if path.length > 1
    parent = (parent[path[i]] ||= {}) for i in [0..path.length - 2]

  parent[path[path.length - 1]] = value
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜