参考文档:
ES6 入门教程https://es6.ruanyifeng.com/
注意:内容较多:只看引用部分的内容即可(代码一眼过搭配理解)
let声名的变量只在所处于的块级有效
let a = 10;
if (true) {
let b = 20;
console.log(b); //可以输出
if (true) {
let c = 30;
console.log(c); //可以输出
}
console.log(c); //报错
}
console.log(a);
console.log(b); //报错
for (let i = 0; i < 2; i++) {}
console.log(i);
//var声名则是2:因为2才会终止循环
//let声名则是报错:因为无法获取块级内部的i
使用let声名变量不能变量提升
console.log(a); //报错 not defined
let a = 20;
console.log(a); //提升变量但是没有赋值
var a = 20;
let声名变量具有暂时性死区(TDZ)
由于没有变量提升引起
不允许重复声名
// 报错
function func() {
let a = 10;
var a = 1;
}
// 报错
function func() {
let a = 10;
let a = 1;
}
function func(arg) {
let arg;
}
func() // 报错
function func(arg) {
{
let arg;
}
}
func() // 不报错
ES5中的没有块级作用域:导致很多时候变量提升引起的变量替换(行为)
在普通循环中特别容易导致泄露成为全局变量
块级作用域之中,函数声明语句的行为类似于
let
,在块级作用域之外不可引用。ES6 的块级作用域必须有大括号,如果没有大括号,JavaScript 引擎就认为不存在块级作用域。
var tmp = new Date();
function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world';
}
}
f(); // undefined
ES6中块级作用域:体现在声名上(let、const)
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}
函数也只声名在当前作用域的顶层
// 不报错
'use strict';
if (true) {
function f() {}
}
// 报错
'use strict';
if (true)
function f() {}
const
声明一个只读的常量:注意是不可以改变的变量同样不可以重复声名
const PI = 3.1415;
PI // 3.1415
PI = 3;
// TypeError: Assignment to constant variable.
var message = "Hello!";
let age = 25;
// 以下两行都会报错
const message = "Goodbye!";
const age = 30;
const
的作用域与let
命令相同:只在声明所在的块级作用域内有效注意:不允许只声名不赋值
if (true) {
const MAX = 5;
}
MAX // Uncaught ReferenceError: MAX is not defined
const
命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用
if (true) {
console.log(MAX); // ReferenceError
const MAX = 5;
}
ES6允许为所有数组元素直接赋值
//原始数组赋值
let a = 1;
let b = 2;
let c = 3;
//解构赋值
let [a, b, c] = [1, 2, 3];
当没有对应的结构值,就会解构失败:没有解构的变量值就等于undefined
变量>值
let [foo] = [];
let [bar, foo] = [1];
不完全解构 :值>变量(但是可以解构成功)
let [x, y] = [1, 2, 3];
x // 1
y // 2
let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4
解构赋值允许指定默认值。
let [foo = true] = [];
foo // true
let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
赋值数组成员如果是undefined不能解构,如果成员是null,则会生效
let [x = 1] = [undefined];
x // 1
let [x = 1] = [null];
x // null
默认值是一个表达式,那么这个表达式是惰性求值的
因为
x
能取到值,所以函数根本不会执行
function f() {
console.log('aaa');
}
let [x = f()] = [1];
默认值可以引用解构赋值的其他变量,但该变量必须已经声明
如果解构就用解构值,否则就用默认值
let [x = 1, y = x] = []; // x=1; y=1
let [x = 1, y = x] = [2]; // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = []; // ReferenceError: y is not defined
直接解构
对象次序不同同样不影响解构
let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"
结构失败:变量值为undefined
let {foo} = {bar: 'baz'};
foo // undefined
同样可以给对象属性值解构
let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'
对象解构可以用于嵌套
let obj = {
p: [
'Hello',
{ y: 'World' }
]
};
let { p, p: [x, { y }] } = obj;
x // "Hello"
y // "World"
p // ["Hello", {y: "World"}]
存在默认值
var {x = 3} = {};
x // 3
var {x, y = 5} = {x: 1};
x // 1
y // 5
var {x: y = 3} = {};
y // 3
var {x: y = 3} = {x: 5};
y // 5
var { message: msg = 'Something went wrong' } = {};
msg // "Something went wrong"