ES6块级做用域 js块级做用域内部函数声明的提高问题

块级做用域的优势javascript

避免变量冲突,好比程序中加载了多个第三方库的时候,若是没有妥善地将内部私有函数或变量隐藏起来,就很容易引起变量冲突;html

能够方便的进行模块管理;java

利于内存回收;(块级做用域里声明的变量在块级做用域执行完以后会所有销毁)es6

es6中的块级做用域chrome

以前在看360的培训课程时,知道了{...}是个块级做用域,错误的认为{...}中声明的函数变量都不会被外界访问到,在看了你不知道的JS以后,发现并非这样的。在块级做用域中使用let声明的变量外界没法访问到。函数

eg:post

var foo = true;
if (foo) {
let bar = foo * 2;
bar = something( bar );
console.log( bar );
} c
onsole.log( bar ); // ReferenceError

let 关键字能够将变量绑定到所在的任意做用域中(一般是 { .. } 内部)。 换句话说, let为其声明的变量隐式地了所在的块做用域。测试

可是这种方式是隐式的,若是没有特别注意哪些块级做用域中有绑定的变量,程序变大了以后,容易形成混乱,因此最好为块做用域显式地创造块来部分解决这个问题。url

1 var foo = true;
2 if (foo) { 3 { // <-- 显式的快 4 let bar = foo * 2; 5 bar = something( bar ); 6 console.log( bar ); 7 } 8 } 9 console.log( bar ); // ReferenceError

 js块级做用域内部函数声明的提高问题spa

在读《你不知道的js》这本书是看到了以下这段代码:

复制代码
1 foo(); // "b"
2 var a = true;
3 if (a) {
4 function foo() { console.log("a"); }
5 }
6 else {
7 function foo() { console.log("b"); }
8 }
复制代码

书上说会打印出'b',由于一个普通块内部的函数声明一般会被提高到所在做用域的顶部, 这个过程不会像下面的代码暗示的那样能够被条件判断所控制。可是也说了这个行为并不可靠, 在 JavaScript 将来的版本中有可能发生改变, 所以应该尽量避免在块内部声明函数。

博主试了在chrome上实验了一下,结果报了VM451:1 Uncaught ReferenceError: a is not defined at <anonymous>:1:1这样的错误,说明if语句中的foo函数声明并无提高到全局做用域的顶部,因此井盖是标准已经发生了改变,在块级做用域中声明的函数并不会提高到其父级做用域的顶部。

博主又打开了IE进行测试,发现IE11会和chrome同样报ReferenceError的错,但IE10及如下都会同书中同样打印出'b'。鉴于新标准的支持程度并不高,仍是尽可能避免在块级做用域内部声明函数。

相关文章
相关标签/搜索