"Code tailor",为前端开发者提供技术相关资讯以及系列基础文章,微信关注“小和山的菜鸟们”公众号,及时获取最新文章。
在开始学习之前,我们想要告诉您的是,本文章是对阮一峰《ECMAScript6 入门》一书中 "let 和 const 命令" 章节的总结,如果您已掌握下面知识事项,则可跳过此环节直接进入题目练习
如果您对某些部分有些遗忘,???? 已经为您准备好了!
在 ES5 中,只有全局作用域和函数作用域,没有块级作用域,这带来了很多不合理的场景,比如:内层变量可能覆盖外层变量、用来计数的循环变量泄露为全局变量。所以,let 和 const 实际上引入了“块级作用域”的概念
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
)关键字声明的变量是块范围的(块是介于{}之间的任何东西)。在每次迭代中,都会有一个新值,每个值的作用域都是独立的。
二: 下面代码输出什么?
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。
有些Java面试题答案是我自己总结的,也有些Java面试题及答案是在网上搜集整理的...
layui table有多行数据,通过外部输入内容,需要定位到指定行,选中改行,对改行...
前言 不知道小伙伴们是否有这样的体验,本地开发项目调试时一切正常,一旦发布到...
前言 在上一篇文章中我为大家介绍了Simpe项目的一些 背景知识 以及如何使用 有限...
简介: 方升架构作为新一代云服务器架构的典范,是阿里云云原生基础设施的最佳实...
Dreamweaver插入网页中的图片大小不合适,想要裁剪图片,该怎么裁剪并编辑图片呢...
这是第 96 篇不掺水的原创,想获取更多原创好文,请搜索公众号关注我们吧~ 本文...
前言 通知栏组件是一个比较常见的组件了,基本上每个站点都会有怎么个组件,主要...
IE6/IE7/IE8/IE9中tbody的innerHTML不能赋值,重现代码如下 复制代码 代码如下: ...
虽然这东西号称跨平台支持浏览器,但建议还是不要使用这个前端框架开发PC端的网...