Javascript 访问多个嵌套对象

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 JS应用程序制作一个全局数据存储——但这是一个关于JS的问题,不是Angular的问题

我已经建立了一个服务来设置数据、获取数据等

看起来是这样的:

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,并获取我所需要的可能的副本,从而更抽象地抽象操作。