一.let
1.不存在变量提升。
var 定义变量时候会有变量提升现象,即变量可以在声明前使用,值为undefined,let改变这种现象,let声明的变量一定要在声明后使用,否则报错。
2.暂时性死区
在代码块内,使用let声明变量之前,这个变量都是不可以使用的,这就叫做暂时性死区(TDZ),这也意味着,typeof检测类型不再是百分百正确,这里注意:如果typeof x;let x 这样会报错,但是typeof x结果是undefined,也就是没有let之前typeof运算符是百分百正确。
3.不允许重复声明
let不允许在相同作用域内,重复声明同一个变量,同理,不能在函数内部重新声明参数
二.块级作用域
1.为了解决①.内层变量可能会覆盖外层变量 ②.用来计数的循环变量泄露为全局变量。只在使用大括号的情况下成立,如果没有大括号就会报错!
2.块级作用域与函数声明
ES5规定函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明
ES6引入块级作用域,明确允许在块级作用域中可以声明函数,并且只针对ES6的浏览器有以下几条规则:①.允许在块级作用域内声明函数,②.函数声明类似于var,即会提升到全局作用域或函数作用域的头部③,同时,函数声明还会提升到所在的块级作用域的头部
3.do表达式
块级作用域是一个语句,将多个操作封装在一起,没有返回值,但是使用do表达式之后,可以得到返回值
let x = do{ let t = f(); t*t+1 } 变量x会得到t*t+1
三.const命令
const声明一个只读的常量,一旦声明,常量的值就不能改变,如果要改变则会报错;作用域和let一样:只在声明所在的块级作用域有效;也是不存在变量提升;存在暂时性死区;不可重复声明。
四.解构赋值
1.解构赋值不得使用圆括号的情况:①.变量声明的语句 ②.函数参数 ③.赋值语句的模式
可以使用圆括号的情况只有一种:赋值语句的非模式部分,可以使用圆括号
({ p: (d) } = {}); //p是模式,d不是模式,所以这个是对的 ({ p: a }) = { p: 42 }; // 是错的
2.用途
(1).交换变量的值
let x = 1; let y = 2; [x, y] = [y, x];
(2).从函数返回多个值(函数只能返回一个值,用解构赋值,将他们放在数组或对象里面返回就可以返回多个值)
function example(){ return [1,2,3] } let [a,b,c] = example //返回一个数组 function example(){ return { foo:1, bar:2 }; } let { foo,bar } = example() //返回一个对象
(3).函数参数的定义
解构赋值可以方便的将一组参数与变量名对应起来
function f([x,y,z]){...} f([1,2,3]) //参数是一组有序的值(参数是数组,有序) function f({x,y,z}){...} f({z:3,y:2,x:1}) //参数是一组无序的值(参数是对象,无序)
(4).提取JSON数据
let jsonData = { id: 42, status: "OK", data: [867, 5309] }; let { id, status, data: number } = jsonData; console.log(id, status, number);
(5)遍历map
const map = new Map(); map.set('first', 'hello'); map.set('second', 'world'); for (let [key, value] of map) { console.log(key + " is " + value); } // first is hello // second is world
如果只想获取键名,或者只想获取键值,可以写成下面这样。
// 获取键名 for (let [key] of map) { // ... } // 获取键值 for (let [,value] of map) { // ... }