Javascript 访问多个嵌套对象
我正在为我的应用Angular JS应用程序制作一个全局数据存储——但这是一个关于JS的问题,不是Angular的问题 我已经建立了一个服务来设置数据、获取数据等 看起来是这样的:Javascript 访问多个嵌套对象,javascript,angularjs,square-bracket,Javascript,Angularjs,Square Bracket,我正在为我的应用Angular JS应用程序制作一个全局数据存储——但这是一个关于JS的问题,不是Angular的问题 我已经建立了一个服务来设置数据、获取数据等 看起来是这样的: angular.module('core').factory('dataService', function(callsService) { let properties = { globalData: {} }; properties.insertData = function(data) {
angular.module('core').factory('dataService', function(callsService) {
let properties = {
globalData: {}
};
properties.insertData = function(data) {
for (let x in data) {
this.globalData[x] = data[x];
}
return;
}
properties.getData = function(data) {
return this.globalData[data];
}
return properties;
});
var property = foo['bar'];
使用该服务的过程如下:
dataService.insertData({foo: 'bar'});
dataService.getData('foo'); // 'bar'
但是,如果存在嵌套数据,则会出现问题,如:
dataService.insertData({foo: {bar: 'hello world'}});
dataService.getData('foo'); // {bar: 'hello world'}
这显然是对象引用的工作方式,但我如何传递以下内容:
dataService.getData('foo.bar'); // 'hello world'
dataService.getData(storage => storage.foo.bar);
或
回到my properties.getData方法,是否有递归或其他方式访问嵌套对象的方法
properties.getData = function(data) {
return this.globalData[data]; // needs to be able to get nested objects
}
最新答复:
我认为这个递归一行程序将完全满足您的要求:
properties.getData = (args, data) => args.length ? this.getData(args.slice(1), data ? data[args[0]] : this.globalData[args[0]]) : data ? data : this.globalData
使用数组中无限多的属性参数或数组索引调用它,如下所示:
dataService.getData(['arrayOfData', 2, 'propOnArrElement', 'subProp', 'desiredValue'])
说明:
函数的签名类似于
getDataargs:数组,数据?:任意:任意
这意味着:
它将数组作为第一个参数,其中包含要遍历以获取嵌套数据的属性/索引的轨迹
它将我们查询的数据结构作为可选的第二个参数,当然,这必然是一个对象或数组
它将返回所需的数据,可以是任何类型。
工作原理:
调用函数时
不应定义第二个参数,以便服务可以访问globalData对象,我们将在后面看到。
检查args数组的长度args.length?,然后
如果它有元素,则递归调用是this.getData,
但是这次,我们将从args数组args.slice1中删除第一个arg,,
数据参数将被重新包含在数据中?。
如果它是在最近的递归调用中定义的,那么第一个arg元素将用于访问数据对象/数组数据[args[0]]上的propertyor索引:,
但是,如果还没有像在初始函数调用中那样定义它,递归调用将使用globalData属性,而不是this.globalData[args[0]]。
随着函数继续其递归过程,数据结构被缩小到更深层次的数据,参数列表也在减少。
一旦args长度解析为false,就没有更多的args可供探索了!,函数不返回另一个递归调用,只返回当前数据对象:data?数据
如果使用空数组调用此函数,将返回整个globalData:this.globalData。
我希望你觉得这本书很有帮助,或者至少是很有趣。今晚洗澡时,当这个解决方案突然出现在我的脑海里时,我确实很兴奋P
奖金材料
下面是一种类似的甚至更好的方法,使用ES6 rest参数和数组。reduce这将允许您在不传递数组的情况下调用函数:
properties.getData = (...args) => args.reduce((data, arg) => data[arg], this.globalData)
这样称呼:
dataService.getData('firstarg', 'secondarg', 'onemorearg', 'desireddata')
令人不满意的原始答案:
由于您返回了数据,因此可以直接在函数调用时访问属性:
const nestedVal = dataService.getData(‘foo’).bar
或:
这似乎是两个问题合一 在回答您的第一个问题时,传递类似dataService.getData'foo.bar'的内容 您可以使用如下字符串访问对象属性:
angular.module('core').factory('dataService', function(callsService) {
let properties = {
globalData: {}
};
properties.insertData = function(data) {
for (let x in data) {
this.globalData[x] = data[x];
}
return;
}
properties.getData = function(data) {
return this.globalData[data];
}
return properties;
});
var property = foo['bar'];
如果愿意,可以使其递归,例如:
var property = foo['bar']['baz'];
关于第二个问题,如果我建议使用箭头函数作为选择器,这可能是?的重复,例如:
dataService.getData('foo.bar'); // 'hello world'
dataService.getData(storage => storage.foo.bar);
而您服务中的功能将是:
properties.getData = function (dataSelector) {
return dataSelector(this.globalData);
}
下面是一个工作示例:
常数数据={
建议1:{
建议2:1
}
};
函数getDatadataSelector{
返回dataSelectordata;
}
const prop2=getDatadata=>data.prop1.prop2;
console.logprop2 使用$parse服务:
演示
角度。模数PP,[]
.runfunction$parse{
var对象={'a':[{'b':{'c':3}]};
var访问器='a[0].b.c';
变量结果=$parseaccessorobject;
console.logresult=>,结果;
//结果=>3
}
在arrow函数选择器上,我得到一个错误,即dataSelector不是一个函数。传递arrow函数时,storage.foo.bar是否应该字符串化?另外,您是否有指向完整文档的链接,说明如何使用箭头函数?我想全面阅读。@4lackof遗憾的是,我正在使用手机,所以我无法编写代码片段,但是您可以阅读MDN中的箭头函数,我将更新答案asap@4lackof我已经用参考资料更新了答案article@4lackof我已经为箭头函数添加了一个工作示例,有这个选项,然而,我希望将整个引用传递给getData,并获取我所需要的可能的副本,从而更抽象地抽象操作。