以点表示法转换字符串以获取对象引用

sou*_*rar 33 javascript syntax object

在javascript中考虑这个对象,

var obj = { a : { b: 1, c: 2 } };
Run Code Online (Sandbox Code Playgroud)

给定字符串"obj.ab"我如何获得这个引用的对象,以便我可以改变它的值?即我希望能够做类似的事情

obj.a.b = 5;
obj.a.c = 10;
Run Code Online (Sandbox Code Playgroud)

其中"obj.ab"和"obj.ac"是字符串(不是obj引用).我遇到过这篇帖子,我可以得到点符号字符串引用obj的值,但我需要的是一种可以获取对象本身的方法吗?

物体的嵌套可能比这更深.也许是

var obj = { a: { b: 1, c : { d : 3, e : 4}, f: 5 } }
Run Code Online (Sandbox Code Playgroud)

geo*_*org 71

要获得该值,请考虑:

function ref(obj, str) {
    str = str.split(".");
    for (var i = 0; i < str.length; i++)
        obj = obj[str[i]];
    return obj;
}

var obj = { a: { b: 1, c : { d : 3, e : 4}, f: 5 } }
str = 'a.c.d'
ref(obj, str) // 3
Run Code Online (Sandbox Code Playgroud)

或者以更奇特的方式,使用reduce:

function ref(obj, str) {
    return str.split(".").reduce(function(o, x) { return o[x] }, obj);
}
Run Code Online (Sandbox Code Playgroud)

在javascript中无法返回对象成员的可赋值引用,您必须使用如下函数:

function set(obj, str, val) {
    str = str.split(".");
    while (str.length > 1)
        obj = obj[str.shift()];
    return obj[str.shift()] = val;
}

var obj = { a: { b: 1, c : { d : 3, e : 4}, f: 5 } }
str = 'a.c.d'
set(obj, str, 99)
console.log(obj.a.c.d) // 99
Run Code Online (Sandbox Code Playgroud)

或者使用ref上面给出的来获取对包含对象的引用,然后将[]运算符应用于它:

parts = str.split(/\.(?=[^.]+$)/)  // Split "foo.bar.baz" into ["foo.bar", "baz"]
ref(obj, parts[0])[parts[1]] = 99
Run Code Online (Sandbox Code Playgroud)


dai*_*gns 9

类似于thg435的答案,但是使用参数检查并支持其中一个祖先级别尚未定义或不是对象的嵌套级别.

setObjByString = function(obj, str, val) {
    var keys, key;
    //make sure str is a string with length
    if (!str || !str.length || Object.prototype.toString.call(str) !== "[object String]") {
        return false;
    }
    if (obj !== Object(obj)) {
        //if it's not an object, make it one
        obj = {};
    }
    keys = str.split(".");
    while (keys.length > 1) {
        key = keys.shift();
        if (obj !== Object(obj)) {
            //if it's not an object, make it one
            obj = {};
        }
        if (!(key in obj)) {
            //if obj doesn't contain the key, add it and set it to an empty object
            obj[key] = {};
        }
        obj = obj[key];
    }
    return obj[keys[0]] = val;
};
Run Code Online (Sandbox Code Playgroud)

用法:

var obj;
setObjByString(obj, "a.b.c.d.e.f", "hello");
Run Code Online (Sandbox Code Playgroud)