关于javascript:ES6-系列一let和const

16次阅读

共计 2489 个字符,预计需要花费 7 分钟才能阅读完成。

“Code tailor”,为前端开发者提供技术相干资讯以及系列根底文章,微信关注“小和山的菜鸟们”公众号,及时获取最新文章。

前言

在开始学习之前,咱们想要告诉您的是,本文章是对阮一峰《ECMAScript6 入门》一书中 “let 和 const 命令 ” 章节的总结,如果您已把握上面常识事项,则可跳过此环节间接进入题目练习

  • 呈现原由
  • 什么是暂时性死区?
  • 什么是变量晋升?
  • 是什么块级作用域?

如果您对某些局部有些忘记,👇🏻 曾经为您筹备好了!

学习链接

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 命令

  • 只在代码块中失效
{
  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 命令

  • 只读常量,一旦申明,就不能扭转,且必须初始化
  • 作用域与 let 雷同
  • 无变量晋升
  • 存在暂时性死区
  • 不可反复申明
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)
}
  • A: 0 1 2 and 0 1 2
  • B: 0 1 2 and 3 3 3
  • C: 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()
  • A: Lydia and undefined
  • B: Lydia and ReferenceError
  • C: ReferenceError and 21
  • D: 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()
  • A: Lydia
  • B: Sarah
  • C: undefined
  • D: ReferenceError

Answer:D

每个函数都有本人的执行上下文(或作用域)。getName 函数首先在它本人的上下文(作用域)中查看它是否蕴含咱们试图拜访的变量名。在本例中,getName 函数蕴含它本人的 name 变量:咱们用 let 关键字和 ’Sarah’ 值申明变量名。

带有 let 关键字(和 const)的变量会被晋升,但与 var 不同的是,不会被初始化。在咱们申明(初始化)它们之前,它们是不可拜访的。这就是所谓的“临时死区”。当咱们试图在申明变量之前拜访它们时,JavaScript 抛出一个 ReferenceError。

如果咱们没有在 getName 函数中申明 name 变量,javascript 引擎就会向下查看作用域链。内部作用域有一个名为 name 的变量,其值为 Lydia。如果那样的话,它会记录为 Lydia。

正文完
 0