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。​