ES6实用的代码片段

Author Avatar
AppleSun 7月 02, 2018

ES6实用的代码片段: 判断元素是否在可视窗口可见、获取滚动条位置、链式调用异步函数、柯里化一个-Promise-函数、运行连续的-promises、休眠、考拉兹算法、两点之间的欧氏距离、精确的几位小数、语音合成,实验阶段、将-JSON-写到文件、根据键值对创建对象、对象转化为键值对、浅克隆对象、Hex转RGB、RGB转hex、是否为数组

Element is visible in viewport (判断元素是否在可视窗口可见)

使用 Element.getBoundingClientRect()window.inner(Width|Height) 值来确定给定元素是否在可视窗口中可见。 省略第二个参数来判断元素是否完全可见,或者指定 true 来判断它是否部分可见。

1
2
3
4
5
6
7
8
9
10
const elementIsVisibleInViewport = (el, partiallyVisible = false) => {
const { top, left, bottom, right } = el.getBoundingClientRect();
return partiallyVisible
? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) &&
((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth))
: top >= 0 && left >= 0 && bottom < = innerHeight && right <= innerWidth;
};
// 举个例子,有一个 100x100 可视窗口, 和一个 10x10px 元素定位在 {top: -1, left: 0, bottom: 9, right: 10}
// elementIsVisibleInViewport(el) -> false (not fully visible)
// elementIsVisibleInViewport(el, true) -> true (partially visible)

Get scroll position (获取滚动条位置)

如果浏览器支持 pageXOffsetpageYOffset ,那么请使用 pageXOffsetpageYOffset ,否则请使用 scrollLeftscrollTop 。 你可以省略 el 参数,默认值为 window

1
2
3
4
const getScrollPos = (el = window) =>
({x: (el.pageXOffset !== undefined) ? el.pageXOffset : el.scrollLeft,
y: (el.pageYOffset !== undefined) ? el.pageYOffset : el.scrollTop});
// getScrollPos() -> {x: 0, y: 200}

Chain asynchronous functions (链式调用异步函数)

循环遍历包含异步事件的函数数组,每次异步事件完成后调用 next

1
2
3
4
5
6
7
8
const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); };
/*
chainAsync([
next => { console.log('0 seconds'); setTimeout(next, 1000); },
next => { console.log('1 second'); setTimeout(next, 1000); },
next => { console.log('2 seconds'); }
])
*/

Promisify (柯里化一个 Promise 函数)

使用柯里化返回一个函数,这个函数返回一个调用原始函数的 Promise 。 使用 ...rest 运算符传入所有参数。

在 Node 8+ 中,你可以使用 util.promisify

1
2
3
4
5
6
7
8
const promisify = func =>
(...args) =>
new Promise((resolve, reject) =>
func(...args, (err, result) =>
err ? reject(err) : resolve(result))
);
// const delay = promisify((d, cb) => setTimeout(cb, d))
// delay(2000).then(() => console.log('Hi!')) -> Promise resolves after 2s

Run promises in series (运行连续的 promises)

使用 Array.reduce() 通过创建 promise 链来运行连续的 promises,其中每个 promise 在 resolved 时返回下一个 promise 。

1
2
3
const series = ps => ps.reduce((p, next) => p.then(next), Promise.resolve());
// const delay = (d) => new Promise(r => setTimeout(r, d))
// series([() => delay(1000), () => delay(2000)]) -> executes each promise sequentially, taking a total of 3 seconds to complete

Sleep (休眠)

延迟执行 async 函数的一部分,通过把它放到 sleep 状态,返回一个 Promise

1
2
3
4
5
6
7
8
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
/*
async function sleepyWork() {
console.log('I\'m going to sleep for 1 second.');
await sleep(1000);
console.log('I woke up after 1 second.');
}
*/

Collatz algorithm(考拉兹算法)

如果 n 是偶数,则返回 n/2 。否则返回 3n+1

1
2
3
const collatz = n => (n % 2 == 0) ? (n / 2) : (3 * n + 1);
// collatz(8) --> 4
// collatz(5) --> 16

愚人码头注:考拉兹猜想(英语:Collatz conjecture),又称为奇偶归一猜想、3n+1猜想、冰雹猜想、角谷猜想、哈塞猜想、乌拉姆猜想或叙拉古猜想,是指对于每一个正整数,如果它是奇数,则对它乘3再加1,如果它是偶数,则对它除以2,如此循环,最终都能够得到1。 – 维基百科。

Distance between two points (两点之间的欧氏距离)

使用 Math.hypot() 计算两点之间的欧氏距离( Euclidean distance)。

1
2
const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0);
// distance(1,1, 2,3) -> 2.23606797749979

愚人码头注: 欧氏距离( Euclidean distance)是一个通常采用的距离定义,它是在m维空间中两个点之间的真实距离。

Round number to n digits (精确的几位小数)

使用 Math.round() 和模板字面量将数字四舍五入为指定的小数位数。 省略第二个参数 decimals,数字将被四舍五入到一个整数。

1
2
const round = (n, decimals=0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`);
// round(1.005, 2) -> 1.01

Speech synthesis (语音合成,实验阶段)

使用 SpeechSynthesisUtterance.voiceindow.speechSynthesis.getVoices() 将消息转换为语音。使用 window.speechSynthesis.speak() 播放消息。

了解有关Web Speech API的SpeechSynthesisUtterance接口的更多信息。

1
2
3
4
5
6
const speak = message => {
const msg = new SpeechSynthesisUtterance(message);
msg.voice = window.speechSynthesis.getVoices()[0];
window.speechSynthesis.speak(msg);
};
// speak('Hello, World') -> plays the message

Write JSON to file (将 JSON 写到文件)

使用 fs.writeFile(),模板字面量 和 JSON.stringify()json 对象写入到 .json 文件中。

1
2
3
const fs = require('fs');
const jsonToFile = (obj, filename) => fs.writeFile(`${filename}.json`, JSON.stringify(obj, null, 2))
// jsonToFile({test: "is passed"}, 'testJsonFile')

Object from key-value pairs (根据键值对创建对象)

使用 Array.reduce() 来创建和组合键值对。

1
2
const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {});
// objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2}

Object to key-value pairs (对象转化为键值对 )

使用 Object.keys()Array.map() 遍历对象的键并生成一个包含键值对的数组。

1
2
const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]);
// objectToPairs({a: 1, b: 2}) -> [['a',1],['b',2]])

Shallow clone object (浅克隆对象)

使用 Object.assign() 和一个空对象({})来创建原始对象的浅拷贝。

1
2
3
4
5
6
const shallowClone = obj => Object.assign({}, obj);
/*
const a = { x: true, y: 1 };
const b = shallowClone(a);
a === b -> false
*/

Hexcode to RGB (Hex转RGB)

使用Array.slice() , Array.map()match() 将十六进制颜色代码(前缀为#)转换为RGB值的字符串。

1
2
const hexToRgb = hex => `rgb(${hex.slice(1).match(/.{2}/g).map(x => parseInt(x, 16)).join()})`
// hexToRgb('#27ae60') -> 'rgb(39,174,96)'

RGB to hexadecimal(RGB转hex)

使用按位左移运算符(<<)和 toString(16) 将给定的RGB参数转换为十六进制字符串,然后使用 padStart(6,'0') 得到一个6位的十六进制值。

1
2
const rgbToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0');
// rgbToHex(255, 165, 1) -> 'ffa501'

Is array(是否为数组)

使用 Array.isArray() 来检查一个值是否为一个数组。

1
2
3
const isArray = val => !!val && Array.isArray(val);
// isArray(null) -> false
// isArray([1]) -> true