javascript引用动态父对象

标签 javascript

我有这个对象,一个类似于谷歌分析的第 3 方跟踪工具。我想用我自己的“缓存”功能来扩展它,该功能可以保存上一次跟踪调用的数据,以便我可以在需要时引用下一次跟踪调用的内容。

这是我目前所拥有的,并且有效:

// Current 3rd party tool, can't really mess with this. 
// It is loaded from an external script
window.someTool={/* stuff */};

// my code
someTool._cache=someTool._cache||{};
someTool._cache._get=function(variabl) {
  var length,index,variabl=(variabl||'').split('.'),
      cache=someTool&&someTool._cache&&someTool._cache._dataLayer||{};
  for (index=0,length=var.length;index<length;index++){
    cache=cache[variabl[index]];
    if (!cache) break;
  }
  return cache;
};

那么我有/做以下事情

// data layer output on initial page that gets wiped later
var dataLayer = {
  'page' : {
    'name' : 'foo',
    'lang' : 'en'
  },
  'events' : {
    'pageView' : true,
    'search' : true
  }
}

// I grab the initial data layer and save it here
someTool._cache._dataLayer = dataLayer;

这让我可以做类似的事情

someTool._cache._get('page'); // returns {'page':{'name':'foo','lang':'en'}
someTool._cache._get('page')['name']; // returns 'foo'
someTool._cache._get('page.lang'); // returns 'en'

所以这对我有用,但问题/目标来了:我想改进我的 _get 函数。也就是说,我不喜欢我必须硬编码 someTool,甚至 _cache,如果我能以某种方式摆动它,_dataLayer

理想情况下,我希望将 someTool._cache._dataLayer 的引用传递/公开给 _get(例如 parent 类型引用)这样如果 someTool_cache_dataLayer 要更改 namespace ,我就不必更新 _get . 但我不确定该怎么做。

这是我目前所拥有的:

(function(tool, cache, dataLayer) {
  var tool = tool || {},
      cache = cache || '_cache',
      dataLayer = dataLayer || '_dataLayer';

  dataLayer = tool[cache][dataLayer] || {};

  tool[cache]._get = function(property) {
    var length, index, property = (property || '').split('.');

    for (index = 0, length = property.length; index < length; index++) {
      dataLayer = dataLayer[property[index]];
      if (!dataLayer) break;
    }

    return dataLayer;
  };
})(someTool, '_cache', '_dataLayer');

这似乎在我第一次调用它时起作用,例如

someTool._cache._get('page')['name'];//返回 'foo'

但在那之后,我得到一个错误:

TypeError: someTool._cache._get(...) 未定义

我觉得它与 dataLayer 失去它的引用或其他东西有关,我不知道(虽然我不确定它是如何工作的第一次......)。我正在做的事情是否有可能,如果可以,我哪里出错了?还是我本来就有的就是我能做的最好的?

最佳答案

I feel like it has something to do with dataLayer losing its reference or something, I dunno (though I'm not sure how it's working first time around..).

发生这种情况的原因是因为您使用的是与在 _get 的闭包中初始化的相同的 dataLayer 以:

  • 存储信息,以及
  • 用作临时循环变量

如果您查看您的代码:

(function(tool, cache, dataLayer) {
  // ...

  // Here you are initializing (or looking up) the dataLayer
  dataLayer = tool[cache][dataLayer] || {};

  tool[cache]._get = function(property) {
    // ...

    for (index = 0, length = property.length; index < length; index++) {
      // here you are overwriting the same dataLayer
      dataLayer = dataLayer[property[index]];
      if (!dataLayer) break;
    }

    return dataLayer;
  };
})(someTool, '_cache', '_dataLayer');

您可以看到您的循环将在每次迭代时覆盖 dataLayer,这意味着第一次查找之后的每次查找很可能都是错误的。

最终,dataLayer 将被 undefined 覆盖,然后任何进一步的查找现在都会破坏代码。

您可以做的是为循环迭代使用另一个变量:

var temp;
for (index = 0, length = property.length; index < length; index++) {
  temp = dataLayer[property[index]];
  if (!temp) break;
}

return temp;

这将使您的 dataLayer 对象完好无损。

关于javascript引用动态父对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38748719/

相关文章:

javascript - 动态引用类属性

javascript - VueJS/Typescript - 找不到模块 './components/Navigation' 或其相应的类型声明

javascript - 选择选择器 Bootstrap 更改 noneSelectedText

javascript - 将变量传递给 ajax 回调

javascript - 类型错误 : Class constructor Client cannot be invoked without 'new'

javascript - 访问 JavaScript 中 some() 函数中使用的对象

javascript - 我如何从跨度中获取 php 值(id)并在模式窗口中使用它

javascript - 为什么我在 'console.log()' AngularJS 中执行 '$http' 时没有从 var_dump 获得结果

javascript - 如何使用谷歌地图 DrawManager 以编程方式绘制多边形

javascript - 如何使 HTML 元素上的焦点元素通过按 Enter 键触发其行为(如单击监听器)