"Code tailor",为前端开发者提供技术相关资讯以及系列基础文章,微信关注“小和山的菜鸟们”公众号,及时获取最新文章。
在开始学习以前,咱们想要告诉您的是,本文章是对阮一峰《ECMAScript6 入门》一书中 "let 和 const 命令" 章节的总结,若是您已掌握下面知识事项,则可跳过此环节直接进入题目练习javascript
若是您对某些部分有些遗忘,👇🏻 已经为您准备好了!前端
let 和 const 的学习java
在 ES5 中,只有全局做用域和函数做用域,没有块级做用域,这带来了不少不合理的场景,好比:内层变量可能覆盖外层变量、用来计数的循环变量泄露为全局变量。因此,let 和 const 实际上引入了“块级做用域”的概念es6
var 命令会发生”变量提高“的的现象,即变量可在声明以前使用,而通常逻辑是先声明变量再去使用变量。故为了纠正此现象,let 命令改变了语法行为,即它所声明的变量必定要在声明后使用。
// var 的状况 console.log(foo) // 输出undefined var foo = 2 // let 的状况 console.log(bar) // 报错ReferenceError let bar = 2
块级做用域可经过新增命令 let 和 const 声明,所声明的变量在指定块的做用域外没法被访问。块级做用域在以下状况被建立:微信
function f1() { let n = 5 if (true) { let n = 10 } console.log(n) // 5 }
{ let a = 10 console.log(a) //10 } console.log(a) //undefined
console.log(bar) // 报错ReferenceError let bar = 2
//报错 let a = 10 let a = 20
const MAX = 1000000 const MIN //SyntaxError const MAX = 10000 //报错
在代码块内,使用 let 命令声明变量以前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)
if (true) { // TDZ开始 tmp = 'abc' // ReferenceError console.log(tmp) // ReferenceError let tmp // TDZ结束 console.log(tmp) // undefined tmp = 123 console.log(tmp) // 123 } //上面代码中,在let命令声明变量tmp以前,都属于变量tmp的“死区”。
一: 下面的代码输出什么?函数
for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 1) } for (let i = 0; i < 3; i++) { setTimeout(() => console.log(i), 1) }
0 1 2
and 0 1 2
0 1 2
and 3 3 3
3 3 3
and 0 1 2
Answer:C学习
因为 JavaScript 中存在事件队列,所以在执行循环以后会调用setTimeout
回调函数。由于第一个循环中的变量 i 是使用var
关键字声明的,因此这个值是全局的。在循环过程当中,咱们使用一元运算符++
将 i 的值每次递增 1。在调用setTimeout
回调函数时,在第一个示例中 i 等于 3。在第二个循环中,变量 i 是使用 let 关键字声明的:使用let
(and const
)关键字声明的变量是块范围的(块是介于{}之间的任何东西)。在每次迭代中,都会有一个新值,每一个值的做用域都是独立的。code
二: 下面代码输出什么?队列
function sayHi() { console.log(name) console.log(age) var name = 'Lydia' let age = 21 } sayHi()
Lydia
and undefined
Lydia
and ReferenceError
ReferenceError
and 21
undefined
and ReferenceError
Answer:D事件
在函数中,咱们首先用 var 关键字声明 name 变量。这意味着变量将被提高(内存空间在建立阶段设置),默认值为 undefined,直到咱们实际到达定义变量的行。咱们尚未在试图记录 name 变量的行中定义变量,因此它仍然保存 undefined 的值。
带有 let 关键字(和 const)的变量会被提高,但与 var 不一样的是,不会被初始化。在咱们声明(初始化)它们以前,它们是不可访问的。这就是所谓的“暂时死区”。当咱们试图在声明变量以前访问它们时,JavaScript 抛出一个 ReferenceError。
三: 下面代码输出什么?
let name = 'Lydia' function getName() { console.log(name) let name = 'Sarah' } getName()
Lydia
Sarah
undefined
ReferenceError
Answer:D
每一个函数都有本身的执行上下文(或做用域)。getName 函数首先在它本身的上下文(做用域)中查看它是否包含咱们试图访问的变量名。在本例中,getName 函数包含它本身的 name 变量:咱们用 let 关键字和'Sarah'值声明变量名。
带有 let 关键字(和 const)的变量会被提高,但与 var 不一样的是,不会被初始化。在咱们声明(初始化)它们以前,它们是不可访问的。这就是所谓的“暂时死区”。当咱们试图在声明变量以前访问它们时,JavaScript 抛出一个 ReferenceError。
若是咱们没有在 getName 函数中声明 name 变量,javascript 引擎就会向下查看做用域链。外部做用域有一个名为 name 的变量,其值为 Lydia。若是那样的话,它会记录为 Lydia。