以点表示法转换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