ES6常用语法
声明
本文参考自http://es6.ruanyifeng.com/
let的使用
let 可用来声明变量
但是,但是,let特殊,它所声明的变量,只在对应的代码块里有效.优点明显,规避全局变量作用域污染的问题
{
var a=1;
let b=2;
}
console.log(a);//1
console.log(b);//报错 b is not defined
for循环遍历数组时let,var声明变量结果存在差异
var定义的i只在for循环里有效,里边的i自始至终都是同一个
var arr = [];
for (var i = 0; i < 10; i++) {
arr[i] = function () {
console.log(i);
};
}
arr[0](); // 10
arr[1](); // 10
arr[2](); // 10
let 声明的i每一轮循环都不同
var arr = [];
for (let i = 0; i < 10; i++) {
arr[i] = function () {
console.log(i);
};
}
arr[0](); // 0
arr[1](); // 1
arr[2](); // 2
let声明的变量不存在变量声明提升
// var 的情况
console.log(a); // 输出undefined
var a= 1;
// let 的情况
console.log(b); // 报错 b is not defined
let b= 2;
暂时性死区
在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)
var num = 123;
if (true) {
num =456; // num is not defined
let num;
}
块级作用域
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}
上面的函数有两个代码块,都声明了变量n,运行后输出 5。这表示外层代码块不受内层代码块的影响。如果两次都使用var定义变量n,最后输出的值才是 10。
const 的使用
const声明常量
const声明一个只读的常量。一旦声明,常量的值就不能改变
const a=1;
a=2;//Assignment to constant variable.分配给常量变量
const声明变量必须立即初始化
const a; // SyntaxError: Missing initializer in const declaration
特点
- 只在块级作用域内有效
- 声明的常量不提升
- 存在暂时性死区
数组的解构赋值
什么是解构
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
//快速为变量赋值
let [a, b, c] = [1, 2, 3];
console.log(a);//1
console.log(b);//2
console.log(c);//3
这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。
使用嵌套数组进行解构的案例
模式一定要匹配
let [a, [[b], c]] = [1, [[2], 3]];
console.log(a)// 1
console.log(b)// 2
console.log(c)// 3
let [ , , c] = ["a", "b", "c"];
console.log(c) // c
let [x, , z] = [1, 2, 3];
console.log(x)// 1
console.log(z)// 3
…语法
let [a, ...b] = [1, 2, 3, 4];
console.log(a) // 1
console.log(b) // [2, 3, 4]
可以很明显的看到,…语法将剩余项匹配成一个数组
解构失败和不完全解构
如果解构不成功,变量的值就等于undefined。
let [x, y, ...z] = [1];
console.log(x) // 1
console.log(y) // undefined
console.log(z) // []
等号左边的模式,只匹配一部分的等号右边的数组。这就是不完全解构,解构依然可以成功。
let [x, y] = [1, 2, 3];
console.log(x) // 1
console.log(y) // 2
let [a, [b], d] = [1, [2, 3], 4];
console.log(a) // 1
console.log(b) // 2
console.log(d) // 4
对象的解构赋值
解构不仅可以用于数组,还可以用于对象。
let { a, b} = { a: "aaa", b: "bbb" };
console.log(a) // aaa
console.log(b) // bbb
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
等号左边的两个变量的次序,与等号右边两个同名属性的次序不一致,但是对取值完全没有影响
let { b, a} = { a: "aaa", b: "bbb" };
console.log(a) // aaa
console.log(b) // bbb
变量没有对应的同名属性,导致取不到值,最后等于undefined。
let { c } = { a: "aaa", b: "bbb" };
console.log(c) // undefined
使用嵌套对象进行解构的案例
注意,此时p是一种模式,不是变量,故不会被赋值
let obj = {
p: [
'Hello',
{ b: 'World' }
]
};
let { p: [a, { b }] } = obj;
console.log(a) // "Hello"
console.log(b) // "World"
如果p也要作为变量赋值,可以写成下面这样。
let obj = {
p: [
'Hello',
{ b: 'World' }
]
};
let { p,p: [a, { b }] } = obj;
console.log(a) // "Hello"
console.log(b) // "World"
console.log(p) // ['Hello', { b: 'World' } ]
上面代码有4次解构赋值,分别是对loc、start、line、column四个属性的解构赋值。注意,最后一次对line,column属性的解构赋值之中,只有line,column是变量,loc和start都是模式,不是变量。
const node = {
loc: {
start: {
line: 1,
column: 5
}
}
};
let { loc, loc: { start }, loc: { start: { line,column }} } = node;
console.log(line) // 1
console.log(column) // 5
console.log(start) // {line: 1, column: 5}
console.log(loc) //{start: {line: 1, column: 5}}
字符串的解构赋值
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。
const [a, b, c,] = '冷月心';
console.log(a) // 冷
console.log(b) // 月
console.log(c) // 心
对字符串的遍历
for (let codePoint of 'foo') {
console.log(codePoint)
}
// f
// o
// o
字符串的includes(), startsWith(), endsWith()方法
传统上,JavaScript 只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中。ES6 又提供了三种新方法。
includes():返回布尔值,表示是否找到了参数字符串。
startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
let s = 'Hello world!';
console.log(s.startsWith('Hello')) // true
console.log(s.endsWith('!')) // true
console.log(s.includes('o')) // true
函数的解构赋值
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
上面代码中,函数add的参数表面上是一个数组,但在传入参数的那一刻,数组参数就被解构成变量x和y。对于函数内部的代码来说,它们能感受到的参数就是x和y。