以点表示法转换string以获取对象引用

在javascript中考虑这个对象,

var obj = { a : { b: 1, c: 2 } }; 

给定string“obj.ab”我怎么能得到这个对象,这样我可以改变它的价值? 即我想能够做类似的事情

 obj.ab = 5; obj.ac = 10; 

其中“obj.ab”和“obj.ac”是string(不是obj引用)。 我遇到这个post ,我可以得到的价值点符号string是指obj,但我需要的是一种方式,我可以得到的对象本身?

对象的嵌套可能比这更深。 也许

 var obj = { a: { b: 1, c : { d : 3, e : 4}, f: 5 } } 

要获得该值,请考虑:

 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 = 'acd' ref(obj, str) // 3 

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

 function ref(obj, str) { return str.split(".").reduce(function(o, x) { return o[x] }, obj); } 

返回一个可分配的引用对象成员是不可能在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 = 'acd' set(obj, str, 99) console.log(obj.acd) // 99 

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

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

与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; }; 

用法:

 var obj; setObjByString(obj, "abcdef", "hello"); 

如果这个javascript运行在浏览器中,那么你可以像这样访问对象:

 window['obj']['a']['b'] = 5 

所以给定的string"obj.ab"你必须拆分它.

 var s = "obj.ab" var e = s.split(".") window[e[0]][e[1]][e[2]] = 5 

下面是一个简单的类包装dict

 class Dots(dict): def __init__(self, *args, **kargs): super(Dots, self).__init__(*args, **kargs) def __getitem__(self, key): try: item = super(Dots, self).__getitem__(key) except KeyError: item = Dots() self.__setitem__(key, item) return Dots(item) if type(item) == dict else item def __setitem__(self, key, value): if type(value) == dict: value = Dots(value) super(Dots, self).__setitem__(key, value) __getattr__ = __getitem__ __setattr__ = __setitem__ 

例:

 >>> a = Dots() >>> abc = 123 >>> abc 123 >>> ab {'c': 123} >>> a {'b': {'c': 123}} 

缺less的键被创build为空Dots()

 >>> if a.Missing: print "Exists" ... >>> a {'Missing': {}, 'b': {'c': 123}} 
 var obj = { a : { b: 1, c: 2 } }; walkObject(obj,"ab"); // 1 function walkObject( obj, path ){ var parts = path.split("."), i=0, part; while (obj && (part=parts[i++])) obj=obj[part]; return obj; } 

或者如果你喜欢你的代码简洁:

 function walkObject( o, path ){ for (var a,p=path.split('.'),i=0; o&&(a=p[i++]); o=o[a]); return o; } 

在javascript中不可能返回一个可赋值的对象成员的引用。 您可以使用一行代码将值赋值给深层对象成员。

 new Function('_', 'val', '_.' + path + ' = val')(obj, value); 

在你的情况下:

 var obj = { a : { b: 1, c: 2 } }; new Function('_', 'val', '_.ab' + ' = val')(obj, 5); // Now obj.ab will be equal to 5