在JavaScript中,我如何dynamic获取对象的嵌套属性

var arr = { foo : 1, bar: { baz : 2 }, bee : 3 } function getter(variable) { return arr[variable]; } 

如果我想要'foo'和'bee',我只需要做arr[variable] – 这很简单,而且function就是这样。

但是,如果我想得到arr.bar.baz AKA arr[bar][baz]

我可以传递给getter函数,让我这样做(当然也让我使用相同的函数获得非嵌套的属性)。

我尝试了getter('bar.baz')getter('[bar][baz]')但那些都不起作用。

我想我可以parsing点或括号(像这里: 在JavaScript中,testing属性深深嵌套在对象图? )。 有更清洁的方法吗? (除了eval当然。)

特别是因为我需要在一个数组元素的循环中正确地设置很多次。

把getter函数的签名改成getter('bar', 'baz')怎么样?

 function getter() { var v = arr; for(var i=0; i< arguments.length; i++) { if(!v) return null; v = v[arguments[i]]; } return v; } 

PS。 没有testing,但你明白了;)

您可以使用基于pathstring的深层访问function。 请注意,在属性名称中不能有任何句点。

 function getPropByString(obj, propString) { if (!propString) return obj; var prop, props = propString.split('.'); for (var i = 0, iLen = props.length - 1; i < iLen; i++) { prop = props[i]; var candidate = obj[prop]; if (candidate !== undefined) { obj = candidate; } else { break; } } return obj[props[i]]; } var obj = {foo: {bar: {baz: 'x'}}}; alert(getPropByString(obj, 'foo.bar.baz')); // x alert(getPropByString(obj, 'foo.bar.baz.buk')); // undefined 

如果访问string为空,则返回该对象。 否则,继续访问path,直到第二个访问者。 如果这是一个ojbect,则返回最后一个object[accessor]值。 否则,返回undefined。

使用lodash库方法将是一个更好的方法: – https://lodash.com/docs#get

 _.get(arr, 'bar.baz'); //returns 2; _.get(arr, 'bar.baz[5].bazzz'); //returns undefined wont throw error; _.get(arr, 'bar.baz[5].bazzz', 'defaultvalue'); // Returns defaultValue because result is undefined 

您可以访问函数参数,您可以传递任意数量的string。 我也推荐使用arr作为更好的封装参数:

 function getter() { var current = arguments[0]; for(var i = 1; i < arguments.length; i++) { if(current[arguments[i]]) { current = current[arguments[i]]; } else { return null; } } return current; } var arr = { foo : 1, bar: { baz : 2 }, bee : 3 }; var baz = getter(arr, 'bar', 'baz'); 

这个博客定义了一个函数来安全地从JS对象读取嵌套的属性

它允许你挖掘一个属性的对象…即。

 safeRead(arr, 'foo', 'bar', 'baz'); 

如果对象链的任何部分为空或未定义,则返回一个空string….

我最近开发了自己的Object方法来获取嵌套在对象和数组之间的对象属性,不pipe它有多深。 它利用了一条recursion的方法。 看一下这个。

 Object.prototype.getNestedValue = function(...a) { return a.length > 1 ? (this[a[0]] !== void 0 && this[a[0]].getNestedValue(...a.slice(1))) : this[a[0]]; }; var myObj = { foo : 1, bar: { baz : 2 }, bee : 3 }, bazval = myObj.getNestedValue("bar","baz"); document.write(bazval);