javascript - 关闭不保持状态变化

标签 javascript

我以为我理解了闭包,但突然间一些简单的东西似乎不起作用。

我使用闭包创建了一个单例。这是一个非常精简的版本:

    Foobar = function() {
        var data = null;

        function init(obj) {
            data = obj;
        }

        return {
            init: init,
            currentValue: data
        }
    }();

由于它是一个单例,我希望当我调用“init”函数时,“data”的值将在唯一存在的对象中更改,并且该值在后续检索中仍然可用'当前值'。

这是我的测试:

    Foobar.init({id:3});
    var test = Foobar.currentValue;

当我在 Firefox (F12) 中单步执行此代码时,我可以看到是的 - 'data' 对 init 函数可见,并且当我执行 'init' 时它正在更改该变量。但是,退出 init 函数并返回执行测试的第二行后,var 'test' 被分配为 null(创建单例时的原始值),而不是我传递给 'init' 函数的对象的副本,正如我所料。

有人可以解答我的困惑吗?

最佳答案

开始
var Foobar = function () {...}();

该语句可以分解为

var Foobar;
Foobar = function () {...}();

在第一行,全局范围注册了 Foobar,没有 rhs 引用,因此 Foobar 在立即调用函数表达式 (IIFE) 之前的任何位置都未定义。

在第二行,执行 IIFE 后,Foobar 被分配给 IIFE 返回的对象,如下所示。

console.log(Foobar); // undefined
var Foobar = function () {...}();
console.log(Foobar); // Object {currentValue: null, init: function}

此时 IIFE 返回的对象可以可视化为

Click to show Diagram of Initial Foobar

然后,当执行Foobar.init({id:3});时。 Foobar 的 init 会请求 rhs 引用,而该引用恰好是 IIFE 的 init。 init 关闭了数据并最终将 data 设置为 {id:3}

Click to show Diagram of after Foobar.init

因此

var test = Foobar.currentValue;

显然其初始状态仍然是一个null值。

使其达到我们的期望。这里至少有两种可能的解决方案:anied曾提到过。

  1. 在 IIFE 中创建另一个带有数据闭包的函数,以便 找回它们。
  2. IIFE 的 init 不是将数据分配给新对象,而是直接初始化 操纵同一个对象本身。

关于javascript - 关闭不保持状态变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43302201/

相关文章:

打字时 javascript 输入格式不起作用

javascript - 如何检查选择器是否匹配 jQuery 中的某些内容?

javascript - 在 gulp 4.0 中使用串行和并行任务

javascript - 未能对先前事件的元素调用操作

javascript - 如何将当前日期转换为数字格式?

javascript - 如何使用 javascript 将文本插入到格式化的弹出窗口中?

javascript - 将下划线替换为空格并将单词大写

javascript - 如何延迟触发 slider 的 jQuery 自动前进脚本中的第一次单击?

javascript - Canvas JS : the chart isnt loaded

javascript - 我应该将 ReactJS 组件的 onClick 逻辑放在什么位置?