Javascript 如何从描述地址的字符串访问对象子对象

Javascript 如何从描述地址的字符串访问对象子对象,javascript,Javascript,如果我有一个像这样的物体 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 = { name: 'Billy', lastName: 'Moon',

如果我有一个像这样的物体

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 = {
    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)

您可以使用
eval
(这通常是个坏主意):

可能更好的方法是:

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'));
函数名称空间(名称空间字符串){
var parts=namespaceString.split('.'),
父项=窗口,
当前部分=“”;
对于(变量i=0,长度=parts.length;i
签出此代码:

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;
}
功能访问(obj、prop、defVal){
var objectNames=prop.split(“.”);
var curObj=obj;
for(var i=0,len=objectNames.length;i

递归方法() 因为
.reduce
不兼容所有浏览器

Feature Chrome  Firefox (Gecko) Internet Explorer   Opera   Safari
Basic support   (Yes)   3.0 (1.9)   9   10.5    4.0
IE 9及以下的垫片…()

只需在调用任何数组上的
.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;
  };
}
if('function'!==typeof Array.prototype.reduce){
Array.prototype.reduce=函数(回调,opt_initialValue){
"严格使用",;
if(null==此| |“未定义”==此的类型){
//目前,所有支持严格模式的现代浏览器都有
//Array.prototype.reduce的本机实现,例如IE8
//不支持严格模式,因此此检查实际上是无用的。
抛出新类型错误(
'Array.prototype.reduce在null或未定义时调用';
}
if('function'!==回调类型){
抛出新类型错误(回调+'不是函数');
}
var指数,价值,
长度=此。长度>>>0,
isValueSet=false;
if(1索引;++索引){
if(this.hasOwnProperty(索引)){
if(isValueSet){
value=回调(value,this[index],index,this);
}
否则{
值=此[索引];
isValueSet=true;
}
}
}
如果(!isValueSet){
抛出新的TypeError(“减少没有初始值的空数组”);
}
返回值;
};
}

我环顾四周,发现: 这似乎是你问题的答案

有几种方法可以用来访问对象中的不同子体。 例如,您可以使用rooter['name']['arbitral']['namespace']['height']来获取height的值。但这似乎并不完全是您想要的


在那篇文章中,答案是你要写一个你自己的方法来完成这项工作,在这个方法中,你需要输入一个由点分隔的字符串并将其拆分。然后你会找到该元素并返回该对象。

可能相关:是-看起来像是同一个问题-搜索起来非常困难。我认为答案似乎有点过头了但是很复杂-必须有一个更简单的方法。向社区提问,我不喜欢这样回答重复问题的有效案例吗?在你的
上使用
.split
“user.arbitral.namespace.height”
strings,因为JavaScript中的对象属性访问被构建为必须使用多个括号符号(
obj['prop1']['prop2']…
)如果你有属性名的字符串。我会将它封装在函数中,就像下面的答案和链接的答案一样,这样你就可以写一次,然后忘记它。不,这个解决方案并不复杂。我不会使用eval…好的,所以你有第二个选项:)这是正确的答案。。。太好了-谢谢!
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;
  };
}