【问题标题】:When using a self-invoking function, why can't I pass references?使用自调用函数时,为什么不能传递引用?
【发布时间】:2018-09-18 06:12:41
【问题描述】:

我最近一直在为某些模块使用IIFE 模式,但遇到了一个我似乎无法找到答案的问题。在我的项目中,我需要传递几个全局变量以供使用。其中之一是全局 googletag 变量,它以默认状态加载,然后在加载外部代码后更改。

但是,它似乎没有更新,因为该模式似乎不是创建引用而是创建副本。我已将问题简化为以下内容。

window.globalLevel = 'First';

var Module = (function(_g){
  function _stuff(){
    return _g;
  }
  return {
      get stuff(){
        return _stuff();
    }
  }
})(window.globalLevel);

// Initial state.
console.log("In Module:", Module.stuff);   // "First"
console.log("In Top:", window.globalLevel) // "First"

// After change.
console.log("--- Changing value ---")
window.globalLevel = 'Second'
console.log("In Module:", Module.stuff);    // "First"
console.log("In Top:", window.globalLevel)  // "Second"

我可以做些什么来解决这个问题吗?我应该做出什么样的调整或考虑?我应该直接在模块中直接引用window.globalReference 吗?看起来很乱,但似乎确实有效。

JS Fiddle

【问题讨论】:

  • JavaScript 没有变量引用。数组和对象作为引用传递,如果您修改对象,它将反映在引用它的所有变量中。但原始类型不是。

标签: javascript iife


【解决方案1】:

您的_stuff 当前正在返回最初通过的参数,即_g。因此,当您使用 window.globalLevel = 'Second' 更改全局变量时,参数不会更改,因此原始参数会被回显。你可以通过返回window.globalLevel来修复它:

window.globalLevel = 'First';

var Module = (function(){
  function _stuff(){
    return window.globalLevel;
  }
  return {
      get stuff(){
        return _stuff();
    }
  }
})(window.globalLevel);

// Initial state.
console.log("In Module:", Module.stuff);   // "First"
console.log("In Top:", window.globalLevel) // "First"

// After change.
console.log("--- Changing value ---")
window.globalLevel = 'Second'
console.log("In Module:", Module.stuff);    // "First"
console.log("In Top:", window.globalLevel)  // "Second"

如果window.globalLevel 是一个对象 而不是原语,则全局变量和参数都将引用内存中相同的底层对象,在这种情况下,您的_g 将起作用:

window.globalLevel = { value: 'First' };

var Module = (function(_g){
  function _stuff(){
    return _g.value;
  }
  return {
      get stuff(){
        return _stuff();
    }
  }
})(window.globalLevel);

// Initial state.
console.log("In Module:", Module.stuff);   // "First"
console.log("In Top:", window.globalLevel.value) // "First"

// After change.
console.log("--- Changing value ---")
window.globalLevel.value = 'Second'
console.log("In Module:", Module.stuff);    // "First"
console.log("In Top:", window.globalLevel.value)  // "Second"

【讨论】:

  • 你现在可以去掉_g参数了。
  • 感谢您的帮助!这有助于我理解这里是如何处理范围的。我的现场项目仍然存在问题,但我不再认为它与此有关。我需要传入的两个库应该是一样的。一个现在可以工作,另一个失败了,所以在初始化时必须做一些奇怪的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-31
  • 2012-01-15
  • 1970-01-01
相关资源
最近更新 更多