与ES5编程方式相比,用ES6方式编程使代码更加高效、易读和易于维护。本章参考ECMAScript6入门教程

1.let取代var

ES6新增两个变量声明方式letconst,其中,let可以完全取代var,且不用担心副作用。

1
2
3
4
5
6
7
8
9
10
11
12
if(true){
let num = 2;
}

for(let i = 0; i < 3; i++){
console.log(i)
}

if(true){
console.log(num2);
let num2 = 5; //Uncaught ReferenceError: num2 is not defined
}

上述代码的优势体现在两个方面,一、前两个代码块如果使用var替代,由于var存在变量提升的作用,想当于声明了两个全局变量,这并非初衷;二、第三段代码使用var代替,代码并不会报错,而是输出undefined,这违反了变量先声明后使用的原则。

2.const常量和线程安全

在let和const之中,应该优先使用const,尤其是在全局范围内,应该设置常量,不应该设置变量。

1
2
3
4
5
6
7
8
9
10
// 旧方式
var a = 1, b = 2, c = 3;

// 一般
const a = 1;
const b = 2;
const c = 3;

// 最好
const [a, b, c] = [1, 2, 3];

使用const有三个好处:一、const提醒阅读代码的人,该声明的量是常量,不可更改;二、使用const声明的量JavaScript解析会内部优化;三、有利于JavaScript后续多线程实现的安全。

3.模板字符串

静态字符串一律使用单引号或反引号,不使用双引号。动态字符串使用反引号。

1
2
const str1 = 'abcde';
const str2 = `abc + ${val}`

4.结构赋值

使用数组成员对变量进行赋值时,优先使用结构赋值。

1
2
3
4
const arr = [5, 56, 68, 2];
const [num1 , num2] = arr;
console.log(num1); // 5
console.log(num2); // 56

函数的参数如果是对象的成员,优先使用结构赋值。

1
2
3
4
5
let obj = {id: 1, name: 'bob', age: 32};
function printInfo({name, age}){
console.log(name + age); // bob32
}
printInfo(obj);

如果函数返回多个值,优先使用对象的解构赋值,而不是数组的解构赋值。

1
2
3
4
function processInput(input) {
return { left, right, top, bottom };
}
const { left, right } = processInput(input);

5.对象

对象定义可以使用简洁表达式,属性名可使用属性表达式。

1
2
3
4
5
6
7
8
9
10
11
12
let name = 'bobo';
let color = 'red';
const obj = { name, color }; // {name: 'bobo', color: 'red'}

let lastWord = 'last word';
const a = {
'first word': 'hello',
[lastWord]: 'world'
};
a['first word'] // "hello"
a[lastWord] // "world"
a['last word'] // "world"

单行定义的对象,最后一个成员不以逗号结尾;多行定义的对象,最后一行用逗号结尾。

1
2
3
4
5
6
const obj1 = {id: 1, attr: 'val'};
const obj2 = {
id: 2,
name: 'lina',
classroom: 324,
};

对象的定义尽量静态化,如果非要修改或者添加属性,使用Object.assign()

1
2
3
4
5
6
const obj = {
name: 'bob',
sex: 'man'
};
const obj2 = Object.assign({id: 1, age: 12}, obj);
console.log(obj2.id); //

定义对象的方法时,可以使用简单表达法。

1
2
3
4
5
6
7
8
let name = 'bobo';
const people = {
name,
age: 65,
sayHi(val){
console.log(val);
}
};

6.数组

使用扩展运算符...拷贝数组。

1
2
3
let arr = [1, 3, 4, 9, 45];
const copy = [...arr];
console.log(copy); // [1, 3, 4, 9, 45]

7.函数

当需要使用立即执行函数、函数表达式、简单的回调函数时可以写成箭头函数的形式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(()=>{
let variable = 1;
//...
})()

let fn = () => {
let variable = 1;
//...
}

let btn = document.getElementById('btn');
btn.addEventListener('click', (e)=>{
console.log(e.target);
});

使用默认值语法设置函数参数的默认值。

1
2
3
function(param1 = 0, param2 = {}){
//...
}

8.Map结构

注意区分 Object 和 Map,只有模拟现实世界的实体对象时,才使用 Object。如果只是需要key: value的数据结构,使用 Map 结构。因为 Map 有内建的遍历机制。

1
2
3
4
5
6
7
8
9
10
let arr = [['id', 34], ['price', 765]];
let map = new Map(arr);

for (let key of map.keys()) {
console.log(key); // id price
}

for (let value of map.values()) {
console.log(value); // 34 765
}

9.Class类

用class可以替代ES5中基于构造函数和原型的类的实现,写法简洁便于理解,extends实现类的继承。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class People{
constructor(age, name){
this.age = age;
this.name = name;
}
sayHi(){
console.log(`Hello, I am ${this.name}, ${this.age} years old.`);
}
}

class Student extends People{
constructor(age, name, role){
super(age, name);
this.role = role;
}
sayRole(){
console.log(`I am a ${this.role}.`);
}
}

let xiaoming = new Student(12, 'xiaoming', 'Students');
xiaoming.sayHi(); // Hello, I am xiaoming, 12 years old.
xiaoming.sayRole(); // I am a Students.

10.模块

JavaScript提供标准的Module语法,以替代之前的require()。

1
2
3
4
5
6
7
8
9
10
11
12
// 导出模块
var obj = {
attribute: 'value',
fn: function(){
console.log(666);
}
};
export default obj;

// 导入上面的模块
import {attribute, fn} from 'module';
fn(); // 666