为什么 IIFE 和常规函数在创建只读变量时表现不同?

Why are IIFE and regular function behaving differently for creating a read-only variable?

我正在尝试使用 IIFE 在 javascript 中创建一个只读变量:

var foo = {a: 1};
var bar = (function(){
    return $.extend({}, foo); // deep copy with Jquery
})();

console.log(foo); // output: {a: 1}
console.log(bar); // output: {a: 1}

bar.a = 2;
console.log(foo); // output: {a: 1}
console.log(bar); // output: {a: 2}

我希望输出始终等于 {a: 1},这是声明一个函数并单独调用它时发生的情况:

var foo = {a: 1};
var bar = function(){
    return $.extend({}, foo); // deep copy with Jquery
};

console.log(foo); // output: {a: 1}
console.log(bar()); // output: {a: 1}

bar().a = 2;
console.log(foo); // output: {a: 1}
console.log(bar()); // output: {a: 1}

为什么立即调用的函数和稍后调用的函数在行为上存在差异?

没有区别 - 如果你调用 IIFE 两次(即复制整个函数两次)你会得到相同的结果。

你的两个例子做的事情完全不同。

在第一个示例中,您将 IIFE 的输出分配给 bar。如果勾选typeof bar,应该是object。如果你愿意,你可以改变它。

在第二个示例中,您将分配给 bar 一个稍后可以调用的函数。如果勾选typeof bar,应该是function。那里没有可以变异的对象。只是一个可以将对象作为参数并产生输出的函数。但是每次输出都是相同的:它将是 foo 的副本。

您在 bar() 的输出中成功地重新分配了 .a 的值,但您没有将其保存在任何地方以便稍后阅读。尝试将最后一行转换为 var baz = bar(); baz.a = 2;console.log(baz); 那么应该是 {a: 2}