通过属性名称数组访问嵌套对象

时间:2014-01-22 16:07:06

标签: javascript arrays object

说我有这样的对象(简化):

var options = {
    boxes: {
        size: {
            x: 15,
            y: 18
        },
    shadow: {
        [...]
    }
};

我有一系列名字:

var names = ['boxes', 'size', 'x'];

根据数组在对象内获取/设置值的简单方法是什么,在本例中它将是:

options.boxes.size.x = somevalue;

有什么想法吗?

2 个答案:

答案 0 :(得分:4)

这样做没有简单的内置方法。你必须编写自己的方法:

function getPath(obj, props) {
    for(var i = 0; i < props.length; i++) {
        if (props[i] in obj) {
            obj = obj[props[i]];
        } else {
            return; // not found
        }
    }

    return obj;
}

function setPath(obj, value, props) {
    for(var i = 0; i < props.length - 1; i++) {
        if (props[i] in obj) {
            obj = obj[props[i]];
        } else {
            return; // not found
        }
    }

    obj[props[i]] = value;
}

alert(getPath(options, names)); // 15
setPath(options, 25, names);  
alert(getPath(options, names)); // 25

答案 1 :(得分:4)

只需使用循环来迭代names并抓取当前名称的下一个嵌套对象。假义值或数组的结尾都应该停止循环。

var obj = options;
var i = 0;

while (obj && i < names.length)
    obj = obj[names[i++]];

或者只使用.reduce()

names.reduce(function(obj, name) {
    return obj && obj[name];
}, options);

当然,如果您愿意,可以命名并重复使用该功能。

function toPropertyIn(obj, name) {
    return obj && obj[name];
}

names.reduce(toPropertyIn, options);

制作一个getter / setter:

function nestedProp(obj, names, value) {
    if (arguments.length > 1)
        var setProp = names.pop();

    var res = names.reduce(function(obj, name) {
        return obj && obj[name];
    }, options);

    if (res && setProp !== undefined)
        res[setProp] = value;
    else
        return res;
}


nestedProp(options, names, "foo"); // to set

var val = nestedProp(options, names); // to get