let
let 和 var 不同之处
- 块级作用域不同。let作用域存在中括号里
{}。 - let
无变量提升 暂时性死区ES6明确规定,如果区块中存在let和const命令,就形成封闭区域。- let在相同作用域下,不允许
重复声明。
var tmp = 123;
if (true) {
tmp = 'abc'; // 报错:ReferenceError,let无变量提升
let tmp;
}
// 报错,不许重复声明
function func() {
let a = 10;
var a = 1;
}
// 报错
function func() {
let a = 10;
let a = 1;
}
块级作用域
- ES5 规定,函数只能在
顶层作用域 / 函数作用域之中声明,不能在块级作用域声明。 - ES6 引入了块级作用域,明确允许在块级作用域之中声明函数ES6规定,块级作用域之中,函数声明语句的行为类似于let,在
块级作用域之外不可引用。
function f() {
console.log('I am outside!');
}
(function () {
if (false) {
// 重复声明一次函数f
function f() {
console.log('I am inside!');
}
}
f();
}());
ES5: result: I am inside! because: ES5 函数会被提升到顶部。
ES6: 报错
- 块级作用域需注意
// 块级作用域内部的函数声明语句,建议不要使用
{
let a = 'secret';
function f() {
return a;
}
}
// 块级作用域内部,优先使用函数表达式
{
let a = 'secret';
let f = function () {
return a;
};
}
const
const声明一个
只读的常量。一旦声明,常量的值不可变。意味着声明必须赋值
const foo;
// SyntaxError: Missing initializer in const declaration
本质并不是变量的值不得改动,而是
变量指向的那个内存地址所保存的数据不得改动。
变量的解构赋值
数组的解构赋值
- “模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。
let [a, ...c] = [1, 2, 3];
a: 1
c: 2,3
- 对于Set解构,也可以使用数组的解构赋值。( 用于数组的去重操作 )
let [x, y, z] = new Set(['a', 'b', 'c']); x // "a"
function clearRepeat(arr){
return [...new Set(arr)] ;
}
- 默认值( 只有成员为undefined时,才会生效)
let [foo = true] = []; // foo = true
let [x = 1] = [undefined]; x // 1
let [x = 1] = [null]; x // null
对象的解构赋值
- 变量必须与属性同名,才能取到正确的值
let { foo, bar } = { foo: 'aaa', bar: 'bbb' }; // foo = "aaa" bar = "bbb"
let { bar, foo } = { foo: 'aaa', bar: 'bbb' }; // foo = "aaa" bar = "bbb"
let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' }; //不简写
2.默认值(对象的属性值严格等于undefined。)
var {x, y = 5} = {x: 1};
x // 1
y // 5
字符串的解构赋值
const [a, b, c, d, e] = 'hello'; // a = "h"
函数的解构赋值
function add( [x, y]){}
function move( {x = 0, y = 0} = {} ){}
function rainy( x = "hello", y = "cc"){} //常用
用途
- 交换变量的值
let x = 1;
let y = 2;
[x, y] = [y, x];
- 函数返回多个值(数组、对象)
- 提取JSON数据
let jsonData = {
id: 42,
status: "OK",
data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number);