nop*_*ole 18 javascript closures scope
在Javascript中,何时创建新范围?我知道的两种情况是:
作为一个注释,任何新的块(在if-then-else,循环,或者只是因为其他原因开始一个块)都不会创建一个新的范围.
是否存在第三种情况,除了上述两种情况之外还会创建新范围?谢谢.
是的,第三种情况是扩展范围链(除了Shog9提到的letmozilla扩展),当评估一个块时:catch
生产Catch:catch(Identifier)Block的计算方法如下:
设C是已传递给此生产的参数.
像表达式new Object()一样创建一个新对象.
在对象Result(2)中创建一个属性.该属性的名称是Identifier,valueisC.值和属性是{DontDelete}.
将结果(2)添加到范围链的前面.
评估阻止.
从作用域链的前面删除结果(2).
返回结果(5).
基本上,创建一个新对象,其中一个名为Identifier的属性被传递给catch,这个新对象被添加到作用域链中,因此我们可以在catch块中使用该标识符.
try {
throw "error";
} catch (identifier) {
// `identifier` accessible here..
}
Run Code Online (Sandbox Code Playgroud)
但请记住,它只是暂时增加当前范围,引入catch标识符,内部声明的任何变量将被简单地提升到其封闭函数的顶部.
还有let语句.请记住let (...) {},喜欢with (...){},不创建变量引入一个新的范围内的块.但是,让定义 可以创建作用于它们定义的块(任何块)的变量.
公平警告:正如评论中指出的那样,虽然它let是JavaScript 1.7(ECMA-262/ECMAScript的Mozilla方言)的一部分,但它不是 ECMAScript的一部分,并且可能不会很快在除Firefox之外的浏览器中工作.另请注意,虽然with可以在ECMAScript的当前实现中用作let语句的替代,但针对挂起的ECMA-262第5版提出的"严格"模式也不允许这样做.如果您担心编写跨平台,面向未来的代码(您应该......),那么请坚持使用范围控制功能!