ES6 块级作用域的理解与用法

发布于 2024-09-13 12:14:34 字数 3046 浏览 21 评论 0

块级作用域

为什么需要块级作用域

ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。

  1. 第一种场景,内层变量可能会覆盖外层变量。
var tmp = new Date()
function f() {
  console.log(tmp)
  if (false) {
    var tmp = 'hello world' // 声明提前
  }
}
f() // undefined
  1. 第二种场景,用来计数的循环变量泄露为全局变量
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
}
  1. ES6 允许块级作用域的任意嵌套
{{{{{let insane = 'Hello World'}}}}}
  1. 外层作用域无法读取内层作用域的变量
{{{{
  {let insane = 'Hello World'}
  console.log(insane) // 报错
}}}}
  1. 内层作用域可以定义外层作用域的同名变量
{{{{
  let insane = 'Hello World'
  {let insane = 'Hello World'}
}}}}
  1. 立即执行函数表达式(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 里面规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式。

  1. 允许在块级作用域内声明函数。
  2. 函数声明类 似于 var ,即会提升到全局作用域或函数作用域的头部。
  3. 同时,函数声明还会提升到所在的块级作用域的头部。

上面三条规则只对 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

和我恋爱吧

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

末蓝

文章 0 评论 0

年少掌心

文章 0 评论 0

党海生

文章 0 评论 0

飞翔的企鹅

文章 0 评论 0

鹿港小镇

文章 0 评论 0

wookoon

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文