[译]12 个 ES6 的小技巧

原文链接:12 tricks for ES6 fun

已经有很多讨论谈到了 ES6 是如何减少我们对于诸如 underscore.jslodash 这类库的需求。我想要用一种稍微不同的方式来展示 ES6 是如何用「非预期」的方式来完成某些常见任务。你可以称之为「ES6 小技巧」。

闲话少叙……

1. 控制台快捷打印日志

知识点:Object Literal Shorthand

1
2
3
4
5
6
let myVar = 'foo';
let otherVar = 2;

// output:
// {myVar: "foo", otherVar: 2}
console.log({myVar, otherVar});

2. 强制转换为字符串

知识点:Template Literal

1
2
3
4
5
6
let num = 2;
let numString = `${num}`;

// output:
// {num: 2, numString: "2"}
console.log({num, numString});

旧做法:

1
2
3
4
5
6
let num = 2;
let numString = num + '';

// output:
// {num: 2, numString: "2"}
console.log({num, numString});

3. 变量交换

知识点:array destructuring

1
2
3
4
let a = 1;
let b = 2;

[b, a] = [a, b];

4. 模拟命名参数

知识点:object destructuring and default values

1
2
3
4
5
6
7
const notify = (msg, {type='info', timeout, close=true} = {}) => {
// display notification
}

notify('Hi!');
notify('Hi!', {type: 'error'});
notify('Hi!', {type: 'warn', close: false});

当第二个参数时 undefined 或者未指定时,将默认为 {}。然后,typeclose 属性也会因为 undefined 或未指定而取默认值。这给函数调用提供了很高的灵活性。

5. 数组克隆

知识点:spread operator

1
2
3
4
5
6
const manipulateList = (list) => {
// defensively copy list
let copiedList = [...list];

// do something with copiedList
};

6. 数组连接

知识点:spread operator

1
2
3
4
5
6
let start = ['do', 're', 'mi'];
let end = ['la', 'ti'];
let scaleFromLiteral = [...start, 'fa', 'so', ...end];

// output: ['do', 're', 'mi', 'fa', 'so', 'la', 'ti']
console.log(scaleFromLiteral);

7. 数组去重

知识点:We can combine Set’s de-duping nature with the spread operator to create a de-dupe array helper

1
2
3
4
5
6
7
8
function dedupe(array) {
return [...new Set(array)];
}

let noDupesArray = dedupe([1, 2, 1, 4, 7, 3, 1]);

// output: [1, 2, 4, 7, 3]
console.log(noDupesArray);

8. 缺失必需参数时报错

知识点:default value

1
2
3
4
5
6
7
8
// Gets called if a parameter is missing and the expression
// specifying the default value is evaluated.
const throwIfMissing = () => {
throw new Error('Missing parameter');
}
const func = (requiredParam = throwIfMissing()) => {
// some implementation
}

9. 超出参数的最大数量时报错

知识点:rest parameters

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function max(...values) {
// only want as many a 3 parameters
// so throw error if over
if (values.length > 3)
throw Error('max 3 parameters allowed!');

// use destructuring to get values
// into variables
let [a, b, c] = values;

return Math.max(a, b, c);
}

// not an error
// returns 3
max(1, 2, 3);

// error!
max(1, 2, 3, 4);

知识点:destructuring

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function max(a, b, c, ...shouldBeEmpty) {
if (shouldBeEmpty.length > 0)
throw Error('max 3 parameters allowed!');

return Math.max(a, b, c);
};

// not an error
// output 6
max(4, 5, 6);

// error!
max(4, 5, 6, 7);

10. 网络请求超时

知识点:Promise.race

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// Wrap `setTimeout` in a promise such that if
// the timeout completes, the promise is rejected
const timeout = (delay = 30000) => {
return new Promise((resolve, reject) => {
let rejectWithError = () => {
reject(new Error('Timed out!'));
};

setTimeout(rejectWithError, delay);
});
}

// Return a promise that will be fulfilled if
// the fetch is fulfilled before the timeout
// is rejected.
const fetchWithTimeout = (url, delay = 3000) => {
// construct an array to pass to `Promise.race`
return Promise.race([
fetch(url),
timeout(delay)
]);
}

// Make an XHR request for the URL that has to
// return a response *before* the 1 s timeout
// happens
fetchWithTimeout('/json/data.json', 1000)
.then(response => {
// successful response before the 1 s timeout
console.log('successful response', response)
})
.catch((e) => {
// Either the timeout occurred or some other error.
// Would need to check the method or use a custom
// `Error` subclass in `timeout`
console.error('request error', e);
});

11. 定义抽象基类

知识点:new.target

抽象基类是一种专门用于继承的类。 它不能直接构建。 主要用例是让继承的类拥有公共接口。 不幸的是,还没有利用 abstract 关键字来创建抽象基类,但是你可以使用类中引入的 new.target 来模拟。

1
2
3
4
5
6
7
8
9
10
11
12
class Note {
constructor() {
if (new.target === Note) {
throw new Error('Note cannot be directly constructed.')
}
}
}
class ColorNote extends Note {

}
let note = new Note(); // error!
let colorNote = new ColorNote(); // ok

12. 定义懒长度函数

知识点:generators

1
2
3
4
5
6
7
8
9
10
11
// Return a new generator that will iterate from `start` for
// `count` number of times
function* range(start, count) {
for (let delta = 0; delta < count; delta++) {
yield start + delta;
}
}

for (let teenageYear of range(13, 7)) {
console.log(`Teenage angst @ ${teenageYear}!`);
}