javascript 以点表示法转换字符串以获取对象引用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10934664/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert string in dot notation to get the object reference
提问by source.rar
Consider this object in javascript,
在javascript中考虑这个对象,
var obj = { a : { b: 1, c: 2 } };
given the string "obj.a.b" how can I get the object this refers to, so that I may alter its value? i.e. I want to be able to do something like
给定字符串“obj.ab”,我怎样才能得到它所指的对象,以便我可以改变它的值?即我希望能够做类似的事情
obj.a.b = 5;
obj.a.c = 10;
where "obj.a.b" & "obj.a.c" are strings (not obj references). I came across this postwhere I can get the value the dot notation string is referring to obj but what I need is a way I can get at the object itself?
其中“obj.ab”和“obj.ac”是字符串(不是 obj 引用)。我遇到了这篇文章,在那里我可以获得点符号字符串所指的 obj 的值,但我需要的是一种可以获取对象本身的方法?
The nesting of the object may be even deeper than this. i.e. maybe
对象的嵌套可能比这更深。即也许
var obj = { a: { b: 1, c : { d : 3, e : 4}, f: 5 } }
回答by georg
To obtain the value, consider:
要获得该值,请考虑:
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
or in a more fancy way, using reduce:
或者以更奇特的方式,使用reduce:
function ref(obj, str) {
return str.split(".").reduce(function(o, x) { return o[x] }, obj);
}
Returning an assignable reference to an object member is not possible in javascript, you'll have to use a function like the following:
在 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
or use ref
given above to obtain the reference to the containing object and then apply the []
operator to it:
或者使用ref
上面给出的来获取对包含对象的引用,然后对其应用[]
运算符:
parts = str.split(/\.(?=[^.]+$)/) // Split "foo.bar.baz" into ["foo.bar", "baz"]
ref(obj, parts[0])[parts[1]] = 99
回答by dairystatedesigns
Similar to thg435's answer, but with argument checks and supports nest levels where one of the ancestor levels isn't yet defined or isn't an object.
类似于 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;
};
Usage:
用法:
var obj;
setObjByString(obj, "a.b.c.d.e.f", "hello");
回答by Plamen
Below is a simple class wrapper around dict
:
下面是一个简单的类包装器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__
Example:
例子:
>>> a = Dots()
>>> a.b.c = 123
>>> a.b.c
123
>>> a.b
{'c': 123}
>>> a
{'b': {'c': 123}}
Missing key are created on the fly as empty Dots()
:
丢失的键被动态创建为空Dots()
:
>>> if a.Missing: print "Exists"
...
>>> a
{'Missing': {}, 'b': {'c': 123}}
回答by WojtekT
If this javascript
runs in a browser then you can access the object like this:
如果这javascript
在浏览器中运行,那么您可以像这样访问对象:
window['obj']['a']['b'] = 5
So given the string "obj.a.b"
you have to split the it by .
:
因此,鉴于字符串,"obj.a.b"
您必须将其拆分为.
:
var s = "obj.a.b"
var e = s.split(".")
window[e[0]][e[1]][e[2]] = 5
回答by Phrogz
var obj = { a : { b: 1, c: 2 } };
walkObject(obj,"a.b"); // 1
function walkObject( obj, path ){
var parts = path.split("."), i=0, part;
while (obj && (part=parts[i++])) obj=obj[part];
return obj;
}
Or if you like your code terse:
或者,如果您喜欢简洁的代码:
function walkObject( o, path ){
for (var a,p=path.split('.'),i=0; o&&(a=p[i++]); o=o[a]);
return o;
}
回答by Harish Anchu
Returning an assignable reference to an object member is not possible in javascript. You can assign value to a deep object member by dot notation with a single line of code like this.
在 javascript 中无法返回对对象成员的可分配引用。您可以使用这样的一行代码通过点表示法为深层对象成员赋值。
new Function('_', 'val', '_.' + path + ' = val')(obj, value);
In you case:
在你的情况下:
var obj = { a : { b: 1, c: 2 } };
new Function('_', 'val', '_.a.b' + ' = val')(obj, 5); // Now obj.a.b will be equal to 5