ES6 块级作用域的理解与用法
块级作用域
为什么需要块级作用域
ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。
- 第一种场景,内层变量可能会覆盖外层变量。
var tmp = new Date()
function f() {
console.log(tmp)
if (false) {
var tmp = 'hello world' // 声明提前
}
}
f() // undefined
- 第二种场景,用来计数的循环变量泄露为全局变量
var s = 'hello'
for (var i = 0; i < s.length; i++) {
console.log(s[i])
}
console.log(i) // 5
let const 实际上为 JavaScript 新增了块级作用域。
function f1() {
let n = 5
if (true) {
let n = 10
}
console.log(n) // 5
}
- ES6 允许块级作用域的任意嵌套
{{{{{let insane = 'Hello World'}}}}}
- 外层作用域无法读取内层作用域的变量
{{{{
{let insane = 'Hello World'}
console.log(insane) // 报错
}}}}
- 内层作用域可以定义外层作用域的同名变量
{{{{
let insane = 'Hello World'
{let insane = 'Hello World'}
}}}}
- 立即执行函数表达式(IIFE)不再必要了
(function () {
var tmp = ...
...
}())
// 块级作用域写法
{
let tmp = ...
...
}
函数块级作用域
ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明
// 情况一(非法但是浏览器可运行)
if (true) {
function f() {}
}
// 情况二(非法但是浏览器可运行)
try {
function f() {}
} catch(e) {
// ...
}
ES6 规定,允许在块级作用域之中创建函数。
块级作用域之中,函数创建语句的行为类似于 let,在块级作用域之外不可引用。
function f() { console.log('I am outside!') }
(function () {
if (false) {
// 重复声明一次函数 f
function f() { console.log('I am inside!') }
}
f()
}())
如果按照 es5 的规则则会得到如下结果
function f() { console.log('I am outside!') }
(function () {
function f() { console.log('I am inside!') }
if (false) {}
f()
}())
// I am inside!
如果按照 es6 的规则则会得到 'I am outside!'
但是浏览器最终运行得到的结果是 'f is not a function'
显然如果改变了块级作用域内声明的函数的处理规则,显然会对老代码产生很大影响。为了减轻因此产生的不兼容问题,
ES6 在附录 B 里面规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式。
- 允许在块级作用域内声明函数。
- 函数声明类 似于 var ,即会提升到全局作用域或函数作用域的头部。
- 同时,函数声明还会提升到所在的块级作用域的头部。
上面三条规则只对 ES6 的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作 let 处理
function f() { console.log('I am outside!') }
(function () {
var f
if (false) {
f = function () { console.log('I am inside!') }
}
f()
}())
// f is not a function
ES6 的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错
// 不报错
'use strict'
if (true) {
function f() {}
}
// 报错
'use strict'
if (true) function f() {}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: TypeScript 常见问题
下一篇: React-router 路由
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论