如果我有这样的对象......
var rooter = {
name: 'Billy',
lastName: 'Moon',
height: '1.4m'
}
我可以从像这样的变量中访问属性......
var name = "name"
console.log(rooter[name])
var arb = "height"
console.log(rooter[arb])
快乐的日子!
但是,如果我有一个更深层次的嵌套对象,我想得到一个字符串中的地址所描述的叶子......
var rooter = {
user: {
firstName: 'Billy',
lastName: 'Moon',
arbitrary: {
namespace: {
height: '1.4m'
}
}
}
}
var name = "user.lastName"
console.log(rooter[name]) // does not work
var arb = "user.arbitrary.namespace.height"
console.log(rooter[arb]) // does not work
没有骰子:(
如何从描述路径的字符串中访问任意对象叶片?
编辑:找到带下划线的方法......
_.reduce(arb.split('.'), function(m, n){ return m[n] }, rooter)
以及IE 9及以上版本......
arb.split('.').reduce(function(m, n){ return m[n] }, rooter)
答案 0 :(得分:1)
我环顾四周,发现: Access object child properties using a dot notation string 这似乎是你问题的答案。
您可以通过几种方式访问对象中的不同后代。 例如,您可以按顺序执行rooter [' name'] ['任意'] ['命名空间'] [' height']获得高度的值。但这似乎认为它可能不是你想要的。
在那篇文章中,答案最终是你要编写一个自己的方法来做到这一点,你将在其中接受一个由点分隔并将其拆分的字符串。然后你会找到该元素并返回该对象。
答案 1 :(得分:0)
您可以使用eval
(这通常是一个坏主意):
eval('rooter.' + name);
可能更好的方法是:
function namespace(namespaceString) {
var parts = namespaceString.split('.'),
parent = window,
currentPart = '';
for(var i = 0, length = parts.length; i < length; i++) {
currentPart = parts[i];
parent[currentPart] = parent[currentPart] || {};
parent = parent[currentPart];
}
return parent;
}
console.log(namespace('rooter.user.firstName'));
答案 2 :(得分:0)
查看此代码:
function access(obj, prop, defVal) {
var objectNames = prop.split(".");
var curObj = obj;
for (var i = 0, len = objectNames.length; i < len; i++) {
curObj = curObj[objectNames[i]];
if (typeof curObj === 'undefined') {
return defVal;
}
}
return curObj;
}
答案 3 :(得分:0)
var rooter = { user: { firstName: 'Billy', lastName: 'Moon', arbitrary: { namespace: { height: '1.4m' } } } };
var arb = "user.arbitrary.namespace.height";
fromPathString = function(pathString, targetObject){
pathString = pathString.split('.');
for(var i = 0; i < pathString.length; i++){
targetObject = (targetObject[pathString[i]])? targetObject[pathString[i]] : targetObject[pathString[i]] = {};
};
return targetObject
}
console.log(fromPathString(arb, rooter))
arb.split('.').reduce(function(m, n){ return m[n] }, rooter)
因为.reduce
与所有浏览器不兼容......
Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support (Yes) 3.0 (1.9) 9 10.5 4.0
为IE 9及以下版本的Shim ...(from MDN)
在任何阵列上调用.reduce
之前放置......
if ('function' !== typeof Array.prototype.reduce) {
Array.prototype.reduce = function(callback, opt_initialValue){
'use strict';
if (null === this || 'undefined' === typeof this) {
// At the moment all modern browsers, that support strict mode, have
// native implementation of Array.prototype.reduce. For instance, IE8
// does not support strict mode, so this check is actually useless.
throw new TypeError(
'Array.prototype.reduce called on null or undefined');
}
if ('function' !== typeof callback) {
throw new TypeError(callback + ' is not a function');
}
var index, value,
length = this.length >>> 0,
isValueSet = false;
if (1 < arguments.length) {
value = opt_initialValue;
isValueSet = true;
}
for (index = 0; length > index; ++index) {
if (this.hasOwnProperty(index)) {
if (isValueSet) {
value = callback(value, this[index], index, this);
}
else {
value = this[index];
isValueSet = true;
}
}
}
if (!isValueSet) {
throw new TypeError('Reduce of empty array with no initial value');
}
return value;
};
}