你不知道的ES2023 | 京东云技术团队

京东云开发者
• 阅读 271

你不知道的ES2023 | 京东云技术团队

6 月 27 日 ECMA 大会批准了 ECMAScript 2023 (es14)规范,意味着新的一些语法将正式成为标准。下面来看看 ECMAScript 2023 有哪些值得我们关注的新特性。

总览:

具体相关提案原文详情可以跳转:已完成提案

•从后往前查找数组

•Hashbang 语法

•Symbol 类型作为 WeakMap 类型的键

•不改变原数组的新的原型方法

从后往前查找数组

在 JavaScript 中,已有的 Array.prototype.find()Array.prototype.findIndex() 两个方法是数组遍历中最常使用的两个方法,通常用来遍历查找数组中符合要求的项,但是目前这两种方法都是从前往后遍历的

const arr = [10, 20, 30, 40, 50];
arr.find(item => item > 30); // 40
arr.findIndex(item => item > 30); // 3

如果想要从后往前遍历,在以前必须先将数组进行反转,然后在对反转后的数组进行遍历查找,这无疑是非常违反直觉的事情,今年的标准就新增了两个数组遍历方法 Array.prototype.findLast()Array.prototype.findLastIndex() ,通过名字也可以看出来他们的作用,用法和 findfindIndex 完全一致,唯一的区别就是它是从后往前遍历的,适用于数组和类数组

findLast(): 返回第一个查找到的元素,如果没有找到,返回 undefined

findLastIndex(): 返回第一个查找到的元素的索引,如果没有找到,返回 -1

const arr = [10, 20, 30, 40, 50];
arr.findLast(item => item > 30); // 50
arr.findLastIndex(item => item > 30); // 4
arr.findLast(item => item > 50); // undefined
arr.findLastIndex(item => item > 50); // -1

Hashbang 语法

Hashbang 注释是一种特殊的注释语法,其行为与单行注释 (//) 完全一样,只是它以 #! 开头,并且只在脚本或模块的最开始处有效。注意,#! 标志之前不能有任何空白字符。注释由 #! 之后的所有字符组成直到第一行的末尾;只允许有一条这样的注释。JavaScript 中的 hashbang 注释类似于 Unix 中的 shebang,它提供了一个特定的 JavaScript 解释器的路径,用它来执行这个脚本。

// 写在脚本文件第一行
#!/usr/bin/env node
'use strict';
console.log(1);


// 写在模块文件第一行
#!/usr/bin/env node
export {};
console.log(1);

这样就可以直接运行脚本代码了

# 以前执行脚本
node demo.js


# 有了 hashbang 之后执行脚本
./demo.js

只有当脚本直接在 shell 中运行时,Hashbang 语法才有语意意义,其他环境下 JavaScript 解释器会把它视为普通注释。

Symbol 类型作为 WeakMap类型的键

在之前,WeakMap 类型只允许使用对象作为键,这是 WeakMap 的一个限制,新的标准扩展了 WeakMap API,允许使用唯一的 Symbol 类型作为键。这样更容易创建和共享 key。

const weakMap = new WeakMap();


// 更具象征意义的key
const key = Symbol('my ref');
const someObject = { /* data */ };


weakMap.set(key, someObject)

除此之外,该标准还解决了另一个在 Stage2 阶段的提案 元组与记录 中引入的问题:如何在原始数据类型中,引用和访问非原始值?由元组和记录的提案中,元组和记录类型中不能包含对象、函数和方法,当这样做时会抛出 TypeError 异常。

const server = #{
  port: 8080,
  handler: function (req) { /* ... */ } // TypeError
}

这种限制存在是因为元组和记录提案的关键目标之一是默认保证数据的深度不可变性和结构相等性。接受 Symbol 值作为 WeakMap 键将允许 JavaScript 库实现自己的类似的 RefConllection 的东西,它可以重用的同时不会随着时间的推移泄漏内存。

class RefBookkeeper {
  #references = new WeakMap();
  ref(obj) {
    const sym = Symbol();
    this.#references.set(sym, obj);
  }
  deref(sym) { return this.#references.get(sym); }
}
globalThis.refs = new RefBookkeeper();


const server = #{
  port: 8080,
  handler: refs.ref(function (req) { /* ... */ })
}
refs.deref(server.handler)({ /* ... */})

不改变原数组的新的原型方法

这次标准新增了 4 个不改变原数组的原型方法:

Array.prototype.toReversed() -> Array

Array.prototype.toSorted(compareFn) -> Array

Array.prototype.toSpliced(start, deleteCount, ...items) -> Array

Array.prototype.with(index, value) -> Array

在 JavaScript 中,数组中的大部分方法是非破坏性的,不会改变原数组,比如 filter() 方法

const arr = ['a', 'b', 'b', 'c'];
const result = arr.filter(x => x !== 'b');
console.log(result); // ['a', 'c']

当然,也存在一些方法,是改变原数组的,比如 **sort()** 方法

const arr = ['c', 'a', 'b'];
const result = arr.sort();
console.log(result); // ['a', 'b', 'c']

在数组方法中,下面的方法是具有破坏性的:

reverse()

sort()

splice()

如果想要使用这些数组方法但是又不改变原数组,我们需要先创建原数组的副本,然后对数组副本使用这些方法。因此就引入了这三个方法的非破坏性的版本,就不需要再创建数组副本进行操作了。

除此之外,还有一个新的非破坏性的方法: with(index, value)。该方法会以非破坏性的方式,替换给定参数 index 位置的数组元素,即 arr[index] = value 的非破坏性版本。

// toReversed()
const arr = ['a', 'b', 'c'];
const result = arr.toReversed();
console.log(result); // ['c', 'b', 'a']
console.log(arr);    // ['a', 'b', 'c']


// toSorted()
const arr = ['c', 'a', 'b'];
const result = arr.toSorted();
console.log(result);  // ['a', 'b', 'c']
console.log(arr);     // ['c', 'a', 'b']


// toSpliced()
const arr = ['a', 'b', 'c', 'd'];
const result = arr.toSpliced(1, 2, 'X');
console.log(result); // ['a', 'X', 'd']
console.log(arr);    // ['a', 'b', 'c', 'd'], 无法再得到已经删除的元素


// with()
const arr = ['a', 'b', 'c'];
const result = arr.with(1, 'X');
console.log(result);  // ['a', 'X', 'c']
console.log(arr);     // ['a', 'b', 'c

这些方法适用于所有数组,也适用于定型数组 TypedArray。在上面提到的元组提案,这些方法也是同样适用的,元组相当于不可变的数组,所以元组不支持破坏性的方法,将这些破坏性的方法引入非破坏性的版本对元组是非常有帮助的。

End

以上就是 ES2023 全部标准化的提案了,目前 Chrome 浏览器已经全部支持,可以在调试工具中尝试新的特性。

作者:京东零售 谢天

来源:京东云开发者社区

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Peter20 Peter20
3年前
mysql中like用法
like的通配符有两种%(百分号):代表零个、一个或者多个字符。\(下划线):代表一个数字或者字符。1\.name以"李"开头wherenamelike'李%'2\.name中包含"云",“云”可以在任何位置wherenamelike'%云%'3\.第二个和第三个字符是0的值wheresalarylike'\00%'4\
Stella981 Stella981
3年前
AssemblyScript 入门指南[每日前端夜话0xEB]
每日前端夜话0xEB每日前端夜话,陪你聊前端。每天晚上18:00准时推送。正文共:2459 字预计阅读时间:10分钟作者:DannyGuo翻译:疯狂的技术宅来源:logrocket!(https://oscimg.oschina.net/oscnet/b880277c594152a503
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Stella981 Stella981
3年前
Node.js 12中的ES模块[每日前端夜话0x9E]
每日前端夜话0x9E每日前端夜话,陪你聊前端。每天晚上18:00准时推送。正文共:2552字预计阅读时间:10 分钟作者:BrianDeSousa翻译:疯狂的技术宅来源:logrocket!(https://oscimg.oschina.net/oscnet/2ccaf94cecd3
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
2020H1中国AI云服务市场规模增长远超预期;C++20 标准正式发布
开发者社区技术周刊又和大家见面了,让我们一起看看,过去一周有哪些值得我们开发者关注的重要新闻吧。!(https://static001.geekbang.org/infoq/0e/0ef0749d6a02848951b542a9d8828656.webp)C20标准正式发布2020H1中国AI云服务市场规模增长远
Wesley13 Wesley13
3年前
2020最佳AI新基建年度榜:九号公司荣获最佳机器人智能驾驶奖
!(https://articlefd.zolimg.com.cn/t_s640x2000/g6/M00/03/05/ChMkKl_QoFIWaCXAACo22TWRIcAAGfwwPRa0oAAKjz972.jpg)2020年是新基建元年,AI、5G、大数据、新能源等成为新基建的关键词。近日雷锋网正式公布【2020最佳AI新基建年度榜】,该榜
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_