给定一个JavaScript对象,
var obj = { a: { b: '1', c: '2' } }
和字符串
"a.b"
我怎么把字符串转换成点符号呢
var val = obj.a.b
如果字符串只是'a',我可以使用obj[a]。但这个更复杂。我想应该有什么简单的方法,但现在想不起来了。
给定一个JavaScript对象,
var obj = { a: { b: '1', c: '2' } }
和字符串
"a.b"
我怎么把字符串转换成点符号呢
var val = obj.a.b
如果字符串只是'a',我可以使用obj[a]。但这个更复杂。我想应该有什么简单的方法,但现在想不起来了。
当前回答
var find = function(root, path) {
var segments = path.split('.'),
cursor = root,
target;
for (var i = 0; i < segments.length; ++i) {
target = cursor[segments[i]];
if (typeof target == "undefined") return void 0;
cursor = target;
}
return cursor;
};
var obj = { a: { b: '1', c: '2' } }
find(obj, "a.b"); // 1
var set = function (root, path, value) {
var segments = path.split('.'),
cursor = root,
target;
for (var i = 0; i < segments.length - 1; ++i) {
cursor = cursor[segments[i]] || { };
}
cursor[segments[segments.length - 1]] = value;
};
set(obj, "a.k", function () { console.log("hello world"); });
find(obj, "a.k")(); // hello world
其他回答
从最初的帖子到现在已经很多年了。 现在有一个很棒的库叫做object-path。 https://github.com/mariocasciaro/object-path
可在NPM和BOWER上使用 https://www.npmjs.com/package/object-path
很简单:
objectPath.get(obj, "a.c.1"); //returns "f"
objectPath.set(obj, "a.j.0.f", "m");
并且适用于深度嵌套的属性和数组。
你可以通过点表示法获得对象成员的值,只需一行代码:
new Function('_', 'return _.' + path)(obj);
对你来说:
var obj = { a: { b: '1', c: '2' } }
var val = new Function('_', 'return _.a.b')(obj);
为了简化,你可以这样写一个函数:
function objGet(obj, path){
return new Function('_', 'return _.' + path)(obj);
}
解释:
Function构造函数创建一个新的Function对象。在JavaScript中,每个函数实际上都是一个function对象。使用function构造函数显式创建函数的语法如下:
new Function ([arg1[, arg2[, ...argN]],] functionBody)
其中arguments(arg1到argN)必须是一个对应于有效javaScript标识符的字符串,functionBody是一个包含包含函数定义的javaScript语句的字符串。
在我们的例子中,我们利用字符串函数体来检索点表示法的对象成员。
希望能有所帮助。
这是我的代码没有使用eval。这也很容易理解。
function value(obj, props) {
if (!props)
return obj;
var propsArr = props.split('.');
var prop = propsArr.splice(0, 1);
return value(obj[prop], propsArr.join('.'));
}
var obj = { a: { b: '1', c: '2', d:{a:{b:'blah'}}}};
console.log(value(obj, 'a.d.a.b')); // Returns blah
我从Ricardo Tomasi的回答中复制了以下内容,并进行了修改,以创建还不存在的子对象。它的效率有点低(更多的if和创建空对象),但应该很好。
它还允许我们做Object。Prop (obj, 'a.b', false)我们之前做不到。不幸的是,它仍然不允许我们赋值为undefined…我还不知道该怎么做。
/**
* Object.prop()
*
* Allows dot-notation access to object properties for both getting and setting.
*
* @param {Object} obj The object we're getting from or setting
* @param {string} prop The dot-notated string defining the property location
* @param {mixed} val For setting only; the value to set
*/
Object.prop = function(obj, prop, val){
var props = prop.split('.'),
final = props.pop(),
p;
for (var i = 0; i < props.length; i++) {
p = props[i];
if (typeof obj[p] === 'undefined') {
// If we're setting
if (typeof val !== 'undefined') {
// If we're not at the end of the props, keep adding new empty objects
if (i != props.length)
obj[p] = {};
}
else
return undefined;
}
obj = obj[p]
}
return typeof val !== "undefined" ? (obj[final] = val) : obj[final]
}
这是我的实现
实现1
Object.prototype.access = function() {
var ele = this[arguments[0]];
if(arguments.length === 1) return ele;
return ele.access.apply(ele, [].slice.call(arguments, 1));
}
实现2(使用数组reduce而不是slice)
Object.prototype.access = function() {
var self = this;
return [].reduce.call(arguments,function(prev,cur) {
return prev[cur];
}, self);
}
例子:
var myobj = {'a':{'b':{'c':{'d':'abcd','e':[11,22,33]}}}};
myobj.access('a','b','c'); // returns: {'d':'abcd', e:[0,1,2,3]}
myobj.a.b.access('c','d'); // returns: 'abcd'
myobj.access('a','b','c','e',0); // returns: 11
它也可以处理数组中的对象
var myobj2 = {'a': {'b':[{'c':'ab0c'},{'d':'ab1d'}]}}
myobj2.access('a','b','1','d'); // returns: 'ab1d'