QQ登录

只需要一步,快速开始

APP扫码登录

只需要一步,快速开始

手机号码,快捷登录

手机号码,快捷登录

查看: 2372|回复: 0

[HTML/CSS/JS] 这些 JS 新语法有点东西啊

[复制链接]

等级头衔

积分成就    金币 : 2841
   泡泡 : 1516
   精华 : 6
   在线时间 : 1294 小时
   最后登录 : 2024-11-21

丰功伟绩

优秀达人突出贡献荣誉管理论坛元老

联系方式
发表于 2021-7-9 09:12:45 | 显示全部楼层 |阅读模式
       TC39是 Ecma International标准化组织旗下的技术委员会的一员,它负责管理着ECMAScript语言和标准化API。ECMAScript语言和标准化API又可以分为两个标准:8 h4 |! |, \# [" q- K9 w
  • 第一个是ECMA-262标准,它包含了语言的语法和核心的API。
  • 另一个标准ECMA-402则包含了一些国际化的API,提供给ECMAScript核心API选择性支持。) j0 Z$ {* y3 x0 I
一、.at(): D( T4 ]+ X* }1 c0 W
       这是个挺不错的新语法。其他有些语言是可以用 arr[-1] 来获取数组末尾的元素,但是对于 JS 来说这是实现不了的事情。因为 [key] 对于对象来说就是在获取 key 对应的值。数组也是对象,对于数组使用 arr[-1] 就是在获取 key 为 -1 的值。
0 L3 B0 C% C1 D! }: m       由于以上原因,我们想获取末尾元素就得这样写 arr[arr.length - 1],以后有了 at 这个方法,我们就可以通过 arr.at(-1) 来拿末尾的元素了,另外同样适用类数组、字符串。
( W1 R4 Z4 [% R% x9 }. @/ B
  1. // Polyfill
  2. function at(n) {
  3.     // ToInteger() abstract op
  4.     n = Math.trunc(n) || 0;
  5.     // Allow negative indexing from the end
  6.     if(n < 0) n += this.length;
  7.     // OOB access is guaranteed to return undefined
  8.     if(n < 0 || n >= this.length) return undefined;
  9.     // Otherwise, this is just normal property access
  10.     return this[n];
  11. }
二、顶层 await* `" v% Z; W2 ~0 ~$ a& {! v
       await 都得用 async 函数包裹大家肯定都知道,这个限制导致我们不能在全局作用域下直接使用 await,必须得包装一下。有了这个提案以后,大家就可以直接在顶层写 await 了,算是一个便利性的提案。目前该提案已经进入阶段 4,板上钉钉会发布。另外其实 Chrome 近期的更新已经支持了该功能。, {) b8 H, ^/ H2 S- \8 Z. u5 k( M  _! \9 |
1.jpg 3 F7 _5 @" h! X  {
三、Error Cause: K8 t" s2 w; s4 k4 ~7 U
       这个语法主要帮助我们便捷地传递Error。一旦可能出错的地方一多,实际就不清楚错误到底是哪里产生的。如果希望外部清楚的知道上下文信息的话,需要封装以下error。& g" r, ~) u3 n$ H9 Q2 E* `6 r) }
  1. async function getSolution() {
  2.   const rawResource = await fetch('//domain/resource-a')
  3.     .catch(err => {
  4.       // How to wrap the error properly?
  5.       // 1. throw new Error('Download raw resource failed: ' + err.message);
  6.       // 2. const wrapErr = new Error('Download raw resource failed');
  7.       //    wrapErr.cause = err;
  8.       //    throw wrapErr;
  9.       // 3. class CustomError extends Error {
  10.       //      constructor(msg, cause) {
  11.       //        super(msg);
  12.       //        this.cause = cause;
  13.       //      }
  14.       //    }
  15.       //    throw new CustomError('Download raw resource failed', err);
  16.     })
  17.   const jobResult = doComputationalHeavyJob(rawResource);
  18.   await fetch('//domain/upload', { method: 'POST', body: jobResult });
  19. }
  20. await doJob(); // => TypeError: Failed to fetch
      那么有了这个语法以后,就可以这样来简化代码:2 X/ C  ?7 O* \: |8 v
  1. async function doJob() {
  2.   const rawResource = await fetch('//domain/resource-a')
  3.     .catch(err => {
  4.       throw new Error('Download raw resource failed', { cause: err });
  5.     });
  6.   const jobResult = doComputationalHeavyJob(rawResource);
  7.   await fetch('//domain/upload', { method: 'POST', body: jobResult })
  8.     .catch(err => {
  9.       throw new Error('Upload job result failed', { cause: err });
  10.     });
  11. }
  12. try {
  13.   await doJob();
  14. } catch (e) {
  15.   console.log(e);
  16.   console.log('Caused by', e.cause);
  17. }
  18. // Error: Upload job result failed
  19. // Caused by TypeError: Failed to fetch
四、管道运算符
* \( ], Y5 o+ ~' ^$ i4 ^, V       这个语法的Star特别多,有5k多个,侧面也能说明是个受欢迎的语法,但是距离发布应该还有好久,毕竟这个提案三四年前就有了,目前还只到阶段 1。这个语法其实在其他函数式编程语言上很常见,主要是为了函数调用方便:' E. v7 c3 s: d8 i& ~( `
  1. let result = exclaim(capitalize(doubleSay("hello")));
  2. result //=> "Hello, hello!"
  3. let result = "hello"
  4.   |> doubleSay
  5.   |> capitalize
  6.   |> exclaim;
  7. result //=> "Hello, hello!"
      这只是对于单个参数的用法,其它的用法有兴趣的读者可以自行阅读提案,其中涉及到了特别多的内容,这大概也是导致推进阶段慢的原因吧。
; d8 O3 K/ m1 N" O2 X4 i五、新的数据结构:Records & Tuples
% D2 F4 G- f8 i  g, v       这个数据结构笔者觉得发布以后会特别有用,总共新增了两种数据结构,可以通过#来声明:
: G# v- f) r, k' L) l( H6 n
#{ x: 1, y: 2 }! L5 e; F' N! p4 W7 }9 |! \: k
#[1, 2, 3, 4]

$ ^* i/ x6 K# b. d4 i     这种数据结构是不可变的,类似 React 中为了做性能优化会引入的 immer 或者 immutable.js,其中的值只接受基本类型或者同是不可变的数据类型。( @1 i0 Q" O- m; J/ B- m
  1. const proposal = #{
  2.   id: 1234,
  3.   title: "Record & Tuple proposal",
  4.   contents: `...`,
  5.   // tuples are primitive types so you can put them in records:
  6.   keywords: #["ecma", "tc39", "proposal", "record", "tuple"],
  7. };
  8. // Accessing keys like you would with objects!
  9. console.log(proposal.title); // Record & Tuple proposal
  10. console.log(proposal.keywords[1]); // tc39
  11. // Spread like objects!
  12. const proposal2 = #{
  13.   ...proposal,
  14.   title: "Stage 2: Record & Tuple",
  15. };
  16. console.log(proposal2.title); // Stage 2: Record & Tuple
  17. console.log(proposal2.keywords[1]); // tc39
  18. // Object functions work on Records:
  19. console.log(Object.keys(proposal)); // ["contents", "id", "keywords", "title"]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|paopaomj.COM ( 渝ICP备18007172号|渝公网安备50010502503914号 )

GMT+8, 2024-11-22 02:07

Powered by paopaomj X3.5 © 2016-2025 sitemap

快速回复 返回顶部 返回列表