这个答案是在早期 JavaScript 实现时代写的。虽然同样的规则var
apply, ECMAScript 2015(又名 ES6) https://www.ecma-international.org/ecma-262/6.0/介绍一下let变量声明语句,遵循“传统”块作用域规则 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let.
的例子let
使用块来确定范围,记录“1”、“2”、“1”:
{ let x = 1; console.log(x); { let x = 2; console.log(x) }; console.log(x) }
The 关于 Block 的 MDN 参考 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block将块的用法总结为:
重要的:JavaScript 确实如此not具有块作用域。通过块引入的变量的作用域为包含函数或脚本,并且设置它们的效果在块本身之外仍然存在。换句话说,块语句不引入作用域。尽管“独立”块是有效的语法,但您不想在 JavaScript 中使用独立块,因为如果您认为它们执行与 C 或 Java 中的此类块类似的操作,那么它们不会执行您认为的操作。
正如 MDN 上所讨论的,该语法完全有效,如下所示{ StatementList }
(aka Block http://es5.github.io/#x12.1)是一个有效的Statement
生产..
However;因为这非常重要:一个新的块会not引入新的范围 https://stackoverflow.com/a/15989608/2864740. Only函数体引入了新的范围。在这种情况下,both the x
and y
变量具有相同的作用域。
另外还有一个FunctionDeclaration
应该出现only as a 顶层陈述 https://stackoverflow.com/questions/14027467/function-declaration-or-function-expression- 也就是说,它必须是直接位于程序或函数体下的语句,而不是块。在这种情况下,声明myfunction
is “在实现之间不能可靠地移植” http://es5.github.io/#x12.
有的是IIFE(立即调用函数表达式) https://stackoverflow.com/questions/18388475/why-and-how-to-use-iife-in-javacript可以使用的模式,虽然它解决了上述技术问题,但我不会在这里推荐它,因为它会使代码复杂化。反而,I会简单地创建更多命名函数(命名函数可以嵌套!),可能在不同的模块或对象中,视情况而定。
var x = "hello";
;(function () {
// New function, new scope
// "y" is created in scope, "x" is accessible through the scope chain
var y = "nice";
// Now VALID because FunctionDeclaration is top-level of Function
function myfunction() {
}
})(); // Invoke immediately
// No "y" here - not in scope anymore