TC39 的提案笔者一直有关注,攒了一些有趣的今天来聊聊。git
PS:提案总共五个阶段,只有到阶段 4 才会被归入到发布规范中,其它的只是有概率会被归入。github
这是个挺不错的新语法。其余有些语言是能够用 arr[-1]
来获取数组末尾的元素,可是对于 JS 来讲这是实现不了的事情。由于 [key]
对于对象来讲就是在获取 key
对应的值。数组也是对象,对于数组使用 arr[-1]
就是在获取 key
为 -1
的值。web
因为以上缘由,咱们想获取末尾元素就得这样写 arr[arr.length - 1]
,之后有了 at
这个方法,咱们就能够经过 arr.at(-1)
来拿末尾的元素了,另外一样适用类数组、字符串。编程
// Polyfill
function at(n) {
// ToInteger() abstract op
n = Math.trunc(n) || 0;
// Allow negative indexing from the end
if(n < 0) n += this.length;
// OOB access is guaranteed to return undefined
if(n < 0 || n >= this.length) return undefined;
// Otherwise, this is just normal property access
return this[n];
}
复制代码
await
都得用 async
函数包裹你们确定都知道,这个限制致使咱们不能在全局做用域下直接使用 await
,必须得包装一下。api
有了这个提案之后,你们就能够直接在顶层写 await
了,算是一个便利性的提案。数组
目前该提案已经进入阶段 4,板上钉钉会发布。另外其实 Chrome 近期的更新已经支持了该功能。性能优化
这个语法主要帮助咱们便捷地传递 Error。一旦可能出错的地方一多,咱们实际就不清楚错误究竟是哪里产生的。若是但愿外部清楚的知道上下文信息的话,咱们须要封装如下 error。markdown
async function getSolution() {
const rawResource = await fetch('//domain/resource-a')
.catch(err => {
// How to wrap the error properly?
// 1. throw new Error('Download raw resource failed: ' + err.message);
// 2. const wrapErr = new Error('Download raw resource failed');
// wrapErr.cause = err;
// throw wrapErr;
// 3. class CustomError extends Error {
// constructor(msg, cause) {
// super(msg);
// this.cause = cause;
// }
// }
// throw new CustomError('Download raw resource failed', err);
})
const jobResult = doComputationalHeavyJob(rawResource);
await fetch('//domain/upload', { method: 'POST', body: jobResult });
}
await doJob(); // => TypeError: Failed to fetch
复制代码
那么有了这个语法之后,咱们能够这样来简化代码:数据结构
async function doJob() {
const rawResource = await fetch('//domain/resource-a')
.catch(err => {
throw new Error('Download raw resource failed', { cause: err });
});
const jobResult = doComputationalHeavyJob(rawResource);
await fetch('//domain/upload', { method: 'POST', body: jobResult })
.catch(err => {
throw new Error('Upload job result failed', { cause: err });
});
}
try {
await doJob();
} catch (e) {
console.log(e);
console.log('Caused by', e.cause);
}
// Error: Upload job result failed
// Caused by TypeError: Failed to fetch
复制代码
这个语法的 Star 特别多,有 5k 多个,侧面也能说明是个受欢迎的语法,可是距离发布应该还有很久,毕竟这个提案三四年前就有了,目前还只到阶段 1。frontend
这个语法其实在其余函数式编程语言上很常见,主要是为了函数调用方便:
let result = exclaim(capitalize(doubleSay("hello")));
result //=> "Hello, hello!"
let result = "hello"
|> doubleSay
|> capitalize
|> exclaim;
result //=> "Hello, hello!"
复制代码
这只是对于单个参数的用法,其它的用法有兴趣的读者能够自行阅读提案,其中涉及到了特别多的内容,这大概也是致使推动阶段慢的缘由吧。
这个数据结构笔者以为发布之后会特别有用,总共新增了两种数据结构,咱们能够经过 #
来声明:
#{ x: 1, y: 2 }
#[1, 2, 3, 4]
这种数据结构是不可变的,相似 React 中为了作性能优化会引入的 immer 或者 immutable.js,其中的值只接受基本类型或者同是不可变的数据类型。
const proposal = #{
id: 1234,
title: "Record & Tuple proposal",
contents: `...`,
// tuples are primitive types so you can put them in records:
keywords: #["ecma", "tc39", "proposal", "record", "tuple"],
};
// Accessing keys like you would with objects!
console.log(proposal.title); // Record & Tuple proposal
console.log(proposal.keywords[1]); // tc39
// Spread like objects!
const proposal2 = #{
...proposal,
title: "Stage 2: Record & Tuple",
};
console.log(proposal2.title); // Stage 2: Record & Tuple
console.log(proposal2.keywords[1]); // tc39
// Object functions work on Records:
console.log(Object.keys(proposal)); // ["contents", "id", "keywords", "title"]
复制代码
以上笔者列举了一部分有意思的 TC39 提案,除了以上这些还有不少提案,各位读者有兴趣的话能够在 TC39 中寻找。