为什么在javascript中的模块模式中实现Lazy函数时范围会发生变化

Why does the scope changes while implementing Lazy function inside module pattern in javascript?

本文关键字:范围 函数 变化 实现 javascript 模块 为什么 模式 Lazy      更新时间:2023-09-26

方法1:

正常中的工作代码

var foo1 = function() {
    var t1 = new Date();
    console.log("initialise - one time only "+this);
    foo1 = function() {
        console.log("Executes everytime after initialising(initialise should not execute again) "+this);
        return t1;
    };
    return foo1();
};

正在执行:foo1();

输出:

第一次

初始化-仅一次[对象窗口]

每次初始化后执行(初始化不应再次执行)[对象窗口]

每隔一次

每次初始化后执行(初始化不应再次执行)[对象窗口]

方法2

im正在javascript中的模块中尝试相同的操作

var tt=(function(){
     var foo = function() {
        var that=this;
        var t = new Date();
        console.log("initialise - one time only" + this);
        foo = function() {
            console.log("Executes everytime after initialising(initialise should not execute again) "+this);
            return t;
        };
        return foo();
    }
    return {
        foo:foo
    };
})();

执行:tt.foo();

输出:

第一次

初始化-仅一次[对象对象]

每次初始化后执行(初始化不应再次执行)[对象窗口]

每隔一次

初始化-仅一次[对象对象]

每次初始化后执行(初始化不应再次执行)[对象窗口]

为什么foo1在方法2中再次初始化

为什么在方法2中,模块模式内部的范围更改为窗口

如何使方法2像方法1一样工作

请从概念上解释方法2的错误。提前谢谢

您可以看到以下行:

initialise - one time only[object Object]
Executes everytime after initialising(initialise should not execute again) [object Window]

在CCD_ 1的每次调用中,因为对初始CCD_;所以你没有执行:

foo = function() {
    console.log("Executes everytime after initialising(initialise should not execute again) "+this);
    return t;
};

但你正在执行:

function () {
    var that=this;
    var t = new Date();
    console.log("initialise - one time only" + this);
    foo = function() {
        console.log("Executes everytime after initialising(initialise should not execute again) "+this);
        return t;
    };
    return foo();
}

第一个日志是initialise - one time only[object Object],因为您使用以下内容调用该方法:

{ foo: foo }

这就像呼叫:

var a = {
   test: function () {
      console.log(this);
   }
}

这里将记录a对象。在第二个console.log中,匿名对象({ foo: foo })没有引用foo,因此使用上下文window调用它,类似于:foo.apply(window)。我希望我的解释是清楚的。

编辑要使第二种方法像第一种方法一样工作,您必须在开头正确引用foo。下面的代码正在修复问题:

var tt=(function(){
     var foo = (function() {
        var that=this;
        var t = new Date();
        console.log("initialise - one time only" + this);
        foo = function() {
            console.log("Executes everytime after initialising(initialise should not execute again) "+this);
            return t;
        };
        return foo;
    }());
    return {
        foo:foo
    };
})();