ES6笔记 - 常用特性

这里列出在项目中常用的ES6相关特性,以便更快的理解和应用ES6。

常用特性

  • 作用域控制 let、const
  • 模板字符串
  • 语法糖 - 箭头函数
  • 解构
  • 类与模块
  • Promise

let & const

  • const 不可重新赋值的值 (常量、配置项以及引用的组件)
  • let 使用let声明的变量只在语句块内有效

let 的使用场景相对较少的,我们只会在 loop(for,while 循环)及少量必须重定义的变量上用到他

let 的使用场景

// 函数体内的变量
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}

// for循环的初始量
for (let i = 0; i < buttons.length; i++) {
// ...
}

const 由于不可以重新赋值的特性,所以可以做更多语法静态分析方面的优化,从而有更高的执行效率。

const 的使用场景

// 定义常量
const REG_GET_INPUT = /^\d{1,3}$/;

// 定义配置项
const config = {
isDev : false,
pubDir: './admin/'
}

// 引入 gulp
const gulp = require('gulp');

模板字符串 Template Strings

增强版的字符串,用反引号(`)标识,支持变量注入与多行文本

//1. 注入变量与方法
const start = 'hi all';

const getName = () => {
return 'jelly';
};

const conf = {
fav: 'Coding'
};

const msg = `${start}, my name is ${getName()}, ${conf.fav} is my favourite`;

// 2. 与引号混用
const wantToSay = `I'm a "tbfed"`;

// 3. 支持多行文本
const slogan =
`
I have a dream today!
`;

// 4. 比较适合写HTML
const resultTpl =
`
<section>
<div>...</div>
</section>
`;

箭头函数 Arrow Function

使用箭头(=>)进行定义的函数,属于匿名函数(Lambda)一类

箭头函数没有独立执行上下文( this ),所以其内部引用 this 对象会直接访问父级。


// 完整写法
const getOptions = (name, key) => {
...
}

// 省略参数括号
const getOptions = key => {
...
}

// 省略参数和方法体括号
const getOptions = key => console.log(key);

// 无参数或方法体,括号不能省略
const noop = () => {};

// 应用示例
let names = [ 'Will', 'Jack', 'Peter', 'Steve', 'John', 'Hugo', 'Mike' ]

let newSet = names
.map((name, index) => {
return {
id: index,
name: name
}
})
.filter(man => man.id % 2 == 0)
.map(man => [man.name])
.reduce((a, b) => a.concat(b))

console.log(newSet) //=> [ 'Will', 'Peter', 'John', 'Mike' ]

解构 Destructuring

用于分解方法的参数、数组、对象中的变量

const bookSet = ['UED', 'TB fed', 'Not find'];
const bookCollection = () => {
return {book1: 'UED', book2: 'TB fed'};
};

// 1. 解构也可以设置默认值
const {book1, book3 = 'Not find'} = bookCollection();

// 2. 解构数组时候是可以跳过其中某几项的
const [book1,,book3] = bookSet; // book1 = 'UED', book3 = 'Not find'

// 3. 解构可以取到指定对象的任何属性,包括它包含的方法
const {length: setLength} = bookSet; // setLength = 3

Rest运算符(解构赋值)/ Spread扩展运算符(…)

// 1. rest 得到的是一个真正的数组而不是一个伪数组
const getOptions = function(...args){
console.log(args.join); // function
};

// 2. rest 可以配合箭头函数使用,达到取得所有参数的目的
const getOptions = (...args) => {
console.log(args); // array
};

// 3. spread 可以用于解构时,聚合所得的值
const [opt1, ...opts] = ['one', 'two', 'three', 'four'];

// 4. spread 可以用于数组定义
const opts = ['one', 'two', 'three', 'four'];
const config = ['other', ...opts];

类与模块 Class & Modules

class 定义一个类

//定义类
class Point {
//构造函数
constructor(x, y) {
//实例属性
this.x = x;
this.y = y;
}
//get和set用于对实例属性自定义存取行为
get prop() {
return 'getter';
}
set prop(value) {
console.log('setter: '+value);
}
//实例方法
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
//静态方法
static classMethod() {
return 'hello';
}
//静态属性
static get HuaChen(){
return 'jelly';
}
}

使用 extend 关键字实现类的继承

class ColorPoint extends Point {
constructor(x, y, color) {
super(x, y); // 调用父类的constructor(x, y)
this.color = color;
}

toString() {
return this.color + ' ' + super.toString(); // 调用父类的toString()
}
}

import 模块引入的方式

import name from "module-name"
import * as name from "module-name"
import { member } from "module-name"
import { member as alias } from "module-name"
import { member1 , member2 } from "module-name"
import { member1 , member2 as alias2 , [...] } from "module-name"
import defaultMember, { member [ , [...] ] } from "module-name"
import defaultMember, * as alias from "module-name"
import defaultMember from "module-name"
import "module-name"

export 模块导出或对外提供接口的方式


export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;
// 等同于
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;

export {firstName, lastName, year};

// 有defautl 与 无default
// 输出
export default function crc32() {
// ...
}
// 输入
import crc32 from 'crc32';

// 输出
export function crc32() {
// ...
};
// 输入
import {crc32} from 'crc32';

// 设置别名
function add(x, y) {
return x * y;
}
export {add as default};

export default命令其实只是输出一个叫做 default 的变量,所以它后面不能跟变量声明语句。

// 正确
export var a = 1;

// 正确
var a = 1;
export default a;

// 错误
export default var a = 1;

Promise

Promise 为异步编程提供统一的解决方案,比传统的回调和事件更加合理有效。


// 1. 多个异步任务同时执行用 Promise.all,顺序执行使用链式调用
// Promise.all
Promise
.all([jsBuildPromise, cssBuildPromise])
.then(() => {
...
});

// 2. Promise 的链式调用需要每一个过程返回一个 Promise 对象才能保证顺序执行
gitPromise
.then(() => git.add()) // 正确,箭头函数简写
.then(() => {
git.commit(); // 错误,函数返回 undefined,会立即执行下一过程
})
.then(() => {
return git.log(); // 正确
});


// 3. Promise 需要调用 catch 方法来捕获错误,而且过程内的错误不会阻塞后续代码执行
new Promise(() => {
f; // not define error !
})
.catch((err) => {
console.log(err) // show 'f is not define'
});
console.log('error test'); // 此行可以被正常执行