这些 JS 新语法有点东西啊!

news/2024/7/19 14:00:54 标签: javascript, html, java, js, twitter
htmledit_views">
js_content">

TC39 的提案笔者一直有关注,攒了一些有趣的今天来聊聊。

PS:提案总共五个阶段,只有到阶段 4 才会被纳入到发布规范中,其它的只是有几率会被纳入。

.at()

这是个挺不错的新语法。其他有些语言是可以用 arr[-1] 来获取数组末尾的元素,但是对于 JS 来说这是实现不了的事情。因为 [key] 对于对象来说就是在获取 key 对应的值。数组也是对象,对于数组使用 arr[-1] 就是在获取 key 为 -1 的值。

由于以上原因,我们想获取末尾元素就得这样写 arr[arr.length - 1],以后有了 at 这个方法,我们就可以通过 arr.at(-1) 来拿末尾的元素了,另外同样适用类数组、字符串。

js">// 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

await 都得用 async 函数包裹大家肯定都知道,这个限制导致我们不能在全局作用域下直接使用 await,必须得包装一下。

有了这个提案以后,大家就可以直接在顶层写 await 了,算是一个便利性的提案。

目前该提案已经进入阶段 4,板上钉钉会发布。另外其实 Chrome 近期的更新已经支持了该功能。

image-20210620162451146

Error Cause

这个语法主要帮助我们便捷地传递 Error。一旦可能出错的地方一多,我们实际就不清楚错误到底是哪里产生的。如果希望外部清楚的知道上下文信息的话,我们需要封装以下 error。

js">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

那么有了这个语法以后,我们可以这样来简化代码:

js">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。

这个语法其实在其他函数式编程语言上很常见,主要是为了函数调用方便:

js">let result = exclaim(capitalize(doubleSay("hello")));
result //=> "Hello, hello!"
let result = "hello"
  |> doubleSay
  |> capitalize
  |> exclaim;
result //=> "Hello, hello!"

这只是对于单个参数的用法,其它的用法有兴趣的读者可以自行阅读提案,其中涉及到了特别多的内容,这大概也是导致推进阶段慢的原因吧。

新的数据结构:Records & Tuples

这个数据结构笔者觉得发布以后会特别有用,总共新增了两种数据结构,我们可以通过 # 来声明:

1.#{ x: 1, y: 2 }2.#[1, 2, 3, 4]

这种数据结构是不可变的,类似 React 中为了做性能优化会引入的 immer 或者 immutable.js,其中的值只接受基本类型或者同是不可变的数据类型。

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"]

http://www.niftyadmin.cn/n/1251364.html

相关文章

事务解释

前言 事务是我们保证数据正确性的重要手段&#xff0c;只要和数据库打交道&#xff0c;就得理解它的 ACID 特性&#xff0c;这也是一个专业程序员应该掌握的基本技能。 事务是什么&#xff1f; 在数据库的世界里&#xff0c;我们最常打交道的是 SQL 操作语句。然而&#xff…

idea中创建EurekaServer注册中心和eureka client和Eureka Server加上安全的用户认证

new -project 选择spring initializr 创建自己的包名&#xff0c;类名。 这一步与创建springboot有区别&#xff0c;画重点了&#xff0c;注意下面的两个红框框 项目名 在Application类上添加注解EnableEurekaServer声明注册中心 在Application.yml配置文件添加图中内容 # eur…

c语言课程内容和要求,C语言程序设计A课程习内容和要求(文本).doc

C语言程序设计A课程习内容和要求(文本)(2011.12.06)C语言程序设计A课程复习内容和要求(文本)敖开云&#xff1a;徐老师&#xff0c;能不能把上学期本课程的考试题电子稿发给我&#xff1f;我在本期的教学中需要用到它。我的Email&#xff1a;aokaiyuncqdd.cq.cn谢谢&#xff01…

学会这20+个JavaScript单行代码,可以让你的代码更加骚气

JavaScript不断发展壮大&#xff0c;因为它是最容易上手的语言之一&#xff0c;因此为市场上的新成为技术怪才打开了大门。&#xff08;问号脸&#xff1f;&#xff09;的确&#xff0c;JavaScript可以做很多出色的事情&#xff01;还有很多东西要学习。而且&#xff0c;无论你…

MySQL中函数field()的用法

MySQL中的field&#xff08;&#xff09;函数&#xff0c;可以用来对SQL中查询结果集进行指定顺序排序。 str与str1&#xff0c;str2&#xff0c;str3&#xff0c;str4比较&#xff0c;其中str指的是字段名字 意为&#xff1a;字段str按照字符串str1&#xff0c;str2&#xff…

gomod 使用

前言 作为官方的包依赖管理工具 gomod&#xff0c;已经被广泛的使用于各个开源项目中了。自从有了它&#xff0c;腰不酸手不疼了&#xff0c;敲代码也更有劲了…o(∩_∩)o 所以&#xff0c;今天我们就来认识认识 gomod &#xff0c;看看它是如何来解决我们的包管理问题&#x…

用c语言编译出星星排列的程序,一个排列生成问题-看问题思考过程

问题是这样的&#xff1a;每次只交换相邻的两个数 如何在n!次交换中找到所有的排列。问题可能有些问题&#xff0c;n!-1次交换更合适&#xff0c;当然说n&#xff01;也可以&#xff0c;但是不要把第一个开始元素算在呢。看到这个问题时大概想到了两个思路&#xff0c;一个根据…

React核心成员表示:JSX就是个错误

近日&#xff0c;在一场关于JSX的讨论中&#xff0c;React核心成员「Sebastian Markbge」&#xff08;Hooks作者&#xff09;表示&#xff1a;他更推崇SwiftUI语法&#xff0c;并认为JSX就是个错误。JSX最早由Facebook提出并推广&#xff0c;在React中被广泛用来描述视图状态。…