# ES6 常用技巧总结
# 拓展运算符
# arguments 转数组
// bad
function sortNumbers() {
return Array.prototype.slice.call(arguments).sort();
}
// good
const sortNumbers = (...numbers) => numbers.sort();
# 调用参数
// bad
Math.max.apply(null, [14, 3, 77]);
// good
Math.max(...[14, 3, 77]);
// 等同于
Math.max(14, 3, 77);
# 构建对象
剔除部分属性,将剩下的属性构建一个新的对象
let [a, b, ...arr] = [1, 2, 3, 4, 5];
const { a, b, ...others } = { a: 1, b: 2, c: 3, d: 4, e: 5 };
有条件的构建对象:
function pick({ id, name, age }) {
return {
guid: id,
...(name && { name }),
...(age && { age })
};
}
合并参数:
let obj1 = { a: 1, b: 2, c: 3 };
let obj2 = { b: 4, c: 5, d: 6 };
let merged = { ...obj1, ...obj2 };
# React
将对象全部传入组件
const parmas = {value1: 1, value2: 2, value3: 3}
<Test {...parmas} />
# 解构赋值
# 对象的基本解构
componentWillReceiveProps(newProps) {
this.setState({
active: newProps.active
})
}
componentWillReceiveProps({active}) {
this.setState({active})
}
handleEvent = () => {
this.setState(({ data }) => ({
data: data.set("key", "value")
}));
};
Promise.all([Promise.resolve(1), Promise.resolve(2)]).then(([x, y]) => {
console.log(x, y);
});
# 对象深度解构
function test({ name } = {}) {
console.log(name || "unknown");
}
let obj = {
a: {
b: {
c: 1
}
}
};
const { a: { b: { c = "" } = "" } = "" } = obj;
# 数组解构
const locale = "中文-上海";
const [language, country] = locale.split("-");
console.log(language); // "中文"
console.log(country); // "上海"
# 变量重命名
let { foo: baz } = { foo: "aaa", bar: "bbb" };
console.log(baz); // "aaa"
# 仅获取部分属性
function test(input) {
return [left, right, top, bottom];
}
const [left, __, top] = test(input);
function test(input) {
return { left, right, top, bottom };
}
const { left, right } = test(input);
# Set 和 Map
# 数组去重
[...new Set(array)];
# 条件语句的优化
const fruitColor = new Map()
.set("red", ["apple", "strawberry"])
.set("yellow", ["banana", "pineapple"])
.set("purple", ["grape", "plum"]);
function test(color) {
return fruitColor.get(color) || [];
}
# Symbol
# 唯一值
var element;
var isMoving = Symbol("isMoving");
if (element[isMoving]) {
smoothAnimations(element);
}
element[isMoving] = true;
# 魔法字符串
魔术字符串指的是在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值。
魔术字符串不利于修改和维护,风格良好的代码,应该尽量消除魔术字符串,改由含义清晰的变量代替。
const TYPE_AUDIO = Symbol();
const TYPE_VIDEO = Symbol();
const TYPE_IMAGE = Symbol();
function handleFileResource(resource) {
switch (resource.type) {
case TYPE_AUDIO:
playAudio(resource);
break;
case TYPE_VIDEO:
playVideo(resource);
break;
case TYPE_IMAGE:
previewImage(resource);
break;
default:
throw new Error("Unknown type of resource");
}
}
# 私有变量
const Example = (function() {
var _private = Symbol("private");
class Example {
constructor() {
this[_private] = "private";
}
getName() {
return this[_private];
}
}
return Example;
})();
var ex = new Example();
console.log(ex.getName()); // private
console.log(ex.name); // undefined
# for of
# 遍历范围
可遍历具有 Symbol[iterator]
属性的对象:
- 数组
- Set
- Map
- 类数组对象,如 arguments 对象、DOM NodeList 对象
- Generator 对象
- 字符串
# 遍历 map
let map = new Map(arr);
// 遍历 key 值
for (let key of map.keys()) {
console.log(key);
}
// 遍历 value 值
for (let value of map.values()) {
console.log(value);
}
// 遍历 key 和 value 值(一)
for (let item of map.entries()) {
console.log(item[0], item[1]);
}
// 遍历 key 和 value 值(二)
for (let [key, value] of data) {
console.log(key);
}
# 函数 - 默认值
doSomething({ foo: 'Hello', bar: 'Hey!', baz: 42 });
// good
function doSomething({ foo = 'Hi', bar = 'Yo!', baz = 13 }) {
...
}
// better
function doSomething({ foo = 'Hi', bar = 'Yo!', baz = 13 } = {}) {
...
}
// good
const Button = ({className = 'default-size'}) => (
<span className={classname}></span>
);
// better
const Button = ({className}) =>
<span className={className}></span>
}
Button.defaultProps = {
className: 'default-size'
}
const required = () => {
throw new Error("Missing parameter");
};
const add = (a = required(), b = required()) => a + b;
add(1, 2); // 3
add(1); // Error: Missing parameter.
# 双冒号运算符
foo::bar;
// 等同于
bar.bind(foo);
foo::bar(...arguments);
// 等同于
bar.apply(foo, arguments);
如果双冒号左边为空,右边是一个对象的方法,则等于将该方法绑定在该对象上面。
var method = obj::obj.foo;
// 等同于
var method = ::obj.foo;
let log = ::console.log;
// 等同于
var log = console.log.bind(console);
# 增强的对象字面量
// bad
const something = "y";
const x = {
something: something
};
// good
const something = "y";
const x = {
something
};
动态属性
const x = {
["a" + "_" + "b"]: "z"
};
console.log(x.a_b); // z
# Promise
fetch("file.json")
.then(data => data.json())
.catch(error => console.error(error))
.finally(() => console.log("finished"));
# Async
async function fetch() {
const value1 = await fetchData();
const value2 = await fetchMoreData(value1);
return fetchMoreData2(value2);
}
错误处理:
// good
function fetch() {
try {
fetchData()
.then(result => {
const data = JSON.parse(result);
})
.catch(err => {
console.log(err);
});
} catch (err) {
console.log(err);
}
}
// better
async function fetch() {
try {
const data = JSON.parse(await fetchData());
} catch (err) {
console.log(err);
}
}
async 地狱:
// bad
(async () => {
const getList = await getList();
const getAnotherList = await getAnotherList();
})();
// good
(async () => {
const listPromise = getList();
const anotherListPromise = getAnotherList();
await listPromise;
await anotherListPromise;
})();
// good
(async () => {
Promise.all([getList(), getAnotherList()]).then(...);
})();
# Class
class Shape {
constructor(width, height) {
this._width = width;
this._height = height;
}
get area() {
return this._width * this._height;
}
}
const square = new Shape(10, 10);
# Decorator
# debounce
class Toggle extends React.Component {
@debounce(500, true)
handleClick() {
console.log("toggle");
}
render() {
return <button onClick={this.handleClick}>button</button>;
}
}
# React 与 Redux
// good
class MyReactComponent extends React.Component {}
export default connect(mapStateToProps, mapDispatchToProps)(MyReactComponent);
// better
@connect(mapStateToProps, mapDispatchToProps)
export default class MyReactComponent extends React.Component {}