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

时间:2016-02-23 06:46:50

标签: javascript closures iife

我正在尝试使用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}

为什么立即调用函数和后来调用函数之间的行为差​​异?

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

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

在第一个示例中,您将var firstMatch = dtInvoicesList.Rows .AsEnumerable()Where(r => r.Field<string>("[Shipment#]") == shipNo && r.Field<string>("[Invoice#]") == invoiceNo) .FirstOrDefault(); if(firstMatch!= null) { firstMatch["IsValid"] = true; //new value. } 分配给IIFE的输出。如果您选中bar,则应为typeof bar。如果你愿意,你可以改变它。

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

您已在foo的输出中成功重新分配.a的值,但您未将其保存在任何位置,以便稍后阅读。尝试将最后一行转换为bar()var baz = bar(); baz.a = 2;应为console.log(baz);