IIFE
在之前,JavaScript 中只有 var
这一种声明变量的方式,并且这种方式声明的变量没有块级作用域,程序员们就发明了一种模仿块级作用域的方法。这种方法被称为“立即调用函数表达式”(immediately-invoked function expressions,IIFE)。
如今,我们不应该再使用 IIFE 了,但是你可以在旧脚本中找到它们。
IIFE 看起来像这样:
(function() {
var message = "Hello";
alert(message); // Hello
})();
这里,创建了一个函数表达式并立即调用。因此,代码立即执行并拥有了自己的私有变量。
函数表达式被括号 (function {...})
包裹起来,因为当 JavaScript 引擎在主代码中遇到 "function"
时,它会把它当成一个函数声明的开始。但函数声明必须有一个函数名,所以这样的代码会导致错误:
// 尝试声明并立即调用一个函数
function() { // <-- SyntaxError: Function statements require a function name
var message = "Hello";
alert(message); // Hello
}();
即使我们说:“好吧,那我们加一个名称吧”,但它仍然不工作,因为 JavaScript 不允许立即调用函数声明:
// 下面的括号会导致语法错误
function go() {
}(); // <-- 不能立即调用函数声明
因此,需要使用圆括号把该函数表达式包起来,以告诉 JavaScript,这个函数是在另一个表达式的上下文中创建的,因此它是一个函数表达式:它不需要函数名,可以立即调用。
除了使用括号,还有其他方式可以告诉 JavaScript 在这我们指的是函数表达式:
// 创建 IIFE 的方法
(function() {
alert("Parentheses around the function");
})();
(function() {
alert("Parentheses around the whole thing");
}());
!function() {
alert("Bitwise NOT operator starts the expression");
}();
+function() {
alert("Unary plus starts the expression");
}();
在上面的所有情况中,我们都声明了一个函数表达式并立即运行它。请再注意一下:如今我们没有理由来编写这样的代码。
总结
var
与 let/const
有两个主要的区别:
var
声明的变量没有块级作用域,它们仅在当前函数内可见,或者全局可见(如果变量是在函数外声明的)。var
变量声明在函数开头就会被处理(脚本启动对应全局变量)。
这些差异使 var
在大多数情况下都比 let
更糟糕。块级作用域是这么好的一个东西。这就是 let
在几年前就被写入到标准中的原因,并且现在(与 const
一起)已经成为了声明变量的主要方式。
IIFE
在之前,JavaScript 中只有 var
这一种声明变量的方式,并且这种方式声明的变量没有块级作用域,程序员们就发明了一种模仿块级作用域的方法。这种方法被称为“立即调用函数表达式”(immediately-invoked function expressions,IIFE)。
如今,我们不应该再使用 IIFE 了,但是你可以在旧脚本中找到它们。
IIFE 看起来像这样:
(function() {
var message = "Hello";
alert(message); // Hello
})();
这里,创建了一个函数表达式并立即调用。因此,代码立即执行并拥有了自己的私有变量。
函数表达式被括号 (function {...})
包裹起来,因为当 JavaScript 引擎在主代码中遇到 "function"
时,它会把它当成一个函数声明的开始。但函数声明必须有一个函数名,所以这样的代码会导致错误:
// 尝试声明并立即调用一个函数
function() { // <-- SyntaxError: Function statements require a function name
var message = "Hello";
alert(message); // Hello
}();
即使我们说:“好吧,那我们加一个名称吧”,但它仍然不工作,因为 JavaScript 不允许立即调用函数声明:
// 下面的括号会导致语法错误
function go() {
}(); // <-- 不能立即调用函数声明
因此,需要使用圆括号把该函数表达式包起来,以告诉 JavaScript,这个函数是在另一个表达式的上下文中创建的,因此它是一个函数表达式:它不需要函数名,可以立即调用。
除了使用括号,还有其他方式可以告诉 JavaScript 在这我们指的是函数表达式:
// 创建 IIFE 的方法
(function() {
alert("Parentheses around the function");
})();
(function() {
alert("Parentheses around the whole thing");
}());
!function() {
alert("Bitwise NOT operator starts the expression");
}();
+function() {
alert("Unary plus starts the expression");
}();
在上面的所有情况中,我们都声明了一个函数表达式并立即运行它。请再注意一下:如今我们没有理由来编写这样的代码。
总结
var
与 let/const
有两个主要的区别:
var
声明的变量没有块级作用域,它们仅在当前函数内可见,或者全局可见(如果变量是在函数外声明的)。var
变量声明在函数开头就会被处理(脚本启动对应全局变量)。
这些差异使 var
在大多数情况下都比 let
更糟糕。块级作用域是这么好的一个东西。这就是 let
在几年前就被写入到标准中的原因,并且现在(与 const
一起)已经成为了声明变量的主要方式。