前言
已经8月份了,马上就是金九银十的日子了,平时我们在公司里边做项目的时候,可能很多语法都不太会用上,久而久之就会忘记了. 趁着掘金8月的活动, 正好整理复习一下这些基础知识,虽然现在es6已经出来很多年了,并不是啥新鲜玩意儿,但是一定是面试必考的考点, 如果到九,十月份的时候,如果考虑要换个工作的话, 就不会显得那么被动了~
作用域与let
废话不多说,我们直接进入正题,在ES5时候, 我们只有两种变量作用域, 一种是全局作用域,另一种是函数作用域, es6后新增了块级作用域. 接着我们来说几个经典的案例
let variable = 1
{
console.log(variable)
let variable = 2
}
大家想一下variable打印出来是多少?
答案:
VM143:3 Uncaught ReferenceError: Cannot access 'variable' before initialization
全局变量有这个变量,块级作用域也有这个变量. 为什么会报一个这个错? 这里就有es6后的几个概念, 暂时性死区 在代码块中, 如果使用了let声明变量, 在声明变量之前是不能使用该变量的, let不会像var一样,进行变量提升的, 在声明之前的这个区域,被叫做暂时性死区
另外一个经典例子
const arr = [1, 2, 3]
for (var i = 0; i < arr.length; i++) {
setTimeout(function() {
console.log(i)
}, 0)
}
我们其实想console出来它的索引,但是如果我们按照前边这么写的话,并不能打印出来我们想要的数据, 打印出来的都是数据的长度出来. // 3, 3, 3
const arr = [1, 2, 3]
for (var i = 0; i < arr.length; i++) {
(function (i) {
setTimeout(function() {
console.log(i)
}, 0)
})(i)
}
如果需要打印出来我们想要的数据,则必须要给我们的定时器加一个闭包. 如上. 为什么需要加一个闭包呢? 因为setTimeout是异步的, 我们会先执行for循环,然后for循环之后,才会打印,这时候,已经for循环走完了,所以打印的都是数据的长度. 所以我们加上一个闭包,闭包有一个作用,它可以缓存变量. 所以可以解决这一个问题. 但是这样写,很复杂,不好懂. 在es6中,我们大可不必这么写. 我们只要把之前代码的var改成let,就解决了这个问题. 因为es6是有块级作用域的,块级作用域就可以理解成之前写的闭包的.
const arr = [1, 2, 3]
for (let i = 0; i < arr.length; i++) {
setTimeout(function() {
console.log(i)
}, 0)
}
const
const,顾名思义是常量,其实和let的作用很相似, 大致可以理解为const是let的特殊的一种, 它除了不可写意外,其他的作用都是一致的.
const PI = 3.14
PI = 3.1415926 // VM176:2 Uncaught TypeError: Assignment to constant variable.
const 声明的常量只是分配的内存不可重新分配,但是如果是没有重新分配内存的修改还是可以的. 比如这样
const USER = { name: 'nancy }
USER.name = 'bob'
如果我们有一种需求,就是常量的对象里边的值也不可修改的话, 那么我们可以这么做
const USER = Object.freeze({name: 'james'})
Object.freeze 它可以冻结对象, 让对象不可修改.
总结
今天我们主要就是复习了一下let和const,以及用他们的时候,存在的一些作用域问题. 我们介绍了什么是暂时性死区, 在用let和const声明变量前的当前作用域中不能使用这个变量. 我们也提到了var存在变量提升的问题, 用var的话,如果不了解原理的话,对代码的执行顺序就会很困惑了. 我们还提到了es6新增的块级作用域,我们可以直接把它理解成闭包的作用. 好了. 今天就复习这些了. 毕竟996. 笑哭~ 明天见啦.