在 IIFE 块中定义一个变量

Defining a variable inside IIFE block

谁能解释一下以下两个 IIFE 块之间的区别:

a) (f1 = function(){console.log('IIFE Block1')})()
b) (var f1 = function(){console.log('IIFE Block2')})()

我知道 "b)" 在执行时会抛出错误。 定义变量"f1"有什么用,它的属性是什么

第一个不使用声明关键字,因此 f1 将成为全局的(这违背了 IIFE 的目的)。但是,这是表达式的合法语法 - 可以调用函数并将结果(如果有)分配给 f1。请注意,这不适用于 use strict 生效。

(f1 = function(){console.log('IIFE Block1')})()

// f1 is Global and can be accessed from anywhere
console.log(f1);

第二个失败,因为它是无效的 IIFE 语法 - 它是一个 声明 和赋值语句,它不是可以计算的表达式。

(var f1 = function(){console.log('IIFE Block2')})()

a 仅在严格模式之外有效。 f1 被隐式定义为全局变量并设置为您的 IIFE 的值。如果您在严格模式下尝试此操作,则会抛出错误,因为 f1 尚未使用 varletconst 或作为函数参数显式声明:

function quirks() {
  (f1 = function() { return 'f1 IIFE'; })();
  return f1;
}
console.log(quirks());

function strict() {
  "use strict";
  
  (f2 = function() { return 'f2 IIFE'; })();
  return f2;
}
console.log(strict());

除了所有出色的答案之外,您会发现其中大部分都是语法允许的。您可以将在 window 对象上运行的第一个方法的相同方法应用于任何其他定义的对象:

(f1 = function(){console.log('IIFE Block1')})()
console.log(f1);

// managed object
var local = {};
(local.f2 = function(){console.log('IIFE Block2')})()
console.log(local.f2);


// or any predefined variable
var f3;
(f3 = function(){console.log('IIFE Block3')})()
console.log(f3);

// just not in the parens
// (var f4 = function(){console.log('IIFE Block4')})()
// console.log(f4);