以下提案很有可能进入今年的 ECMAScript 版本(顺便吆喝一声,技术大厂,前后端测试捞人,感兴趣→机会): ECMAScript 更新JS的新版本总是会引起轰动。自 ES6 更新以来,每年都会有新版本,我们预计今年(ES2024)将在 6 月左右发布。 ES6 是一个大规模版本,是在其前身 ES5六年后发布的。 浏览器供应商和 JavaScript 开发人员对大量需要采用和学习的新功能感到不知所措。从那时起,为了防止新功能同时出现如此大的下降,每年都有一个发布周期。 这个年度发布周期涉及提出任何新功能,然后由委员会讨论、评估和投票,然后再将其添加到语言中。此过程还允许浏览器在提案正式添加到语言之前尝试实现这些提案,这可能有助于解决任何实现问题。 如前所述,JavaScript(或 ECMAScript)的新功能由技术委员会39(TC39)决定。TC39 由来自所有主要浏览器供应商的代表以及 JavaScript 专家组成。他们定期开会讨论该语言的新功能以及如何实现这些功能。新功能以提案形式提出(由任何人提出),然后委员会成员投票决定每个提案是否可以进入下一阶段。每个提案有 4 个阶段;一旦提案达到第 4 阶段,预计将被包含在下一版本的 ES 中。 ES 规范的一个重要部分是它必须向后兼容。这意味着任何新功能都不能通过改变 ES 之前版本的工作方式来破坏互联网。 因此,他们无法改变现有方法的工作方式,只能添加新方法,因为任何使用可能预先存在的方法运行的网站都将面临崩溃的风险。 Temporal在《2022年JS现状》调查中,第三个最常见的答案是“您认为 JavaScript 目前缺少什么?” 是更好的日期管理。 这导致了Temporal提案的 产生,它提供了一个标准的全局对象来替换该Date对象,并修复了多年来在 JavaScript 中处理日期时给开发人员带来很大痛苦的一些问题。 在 JavaScript 中处理日期几乎总是一项可怕的任务;必须处理微小但令人恼火的不一致,例如疯狂的月份索引为零,但月份中的日期从 1 开始。 日期的困难导致流行的库如Moment、Day.JS和 date-fns出现,试图解决这些问题。然而,该TemporalAPI 旨在本地解决所有问题。 Temporal将支持多个时区和开箱即用的非公历,并将提供一个简单易用的 API,使从字符串解析日期变得更加容易。此外,所有Temporal对象都是不可变的,这将有助于避免任何意外的日期更改错误。 让我们看一下 API 提供的最有用方法的一些示例Temporal。 Temporal.Now.Instant()Temporal.Now.Instant()将返回一个最接近纳秒的 DateTime 对象。您可以使用from如下方法指定特定日期: const olympics = Temporal.Instant.from('2024-07-26T20:24:00+01:00');
这将创建一个 DateTime 对象,表示今年晚些时候巴黎奥运会将于 2024 年 7 月 26 日 20:24(UTC)开始。 PlainDate()这允许您只创建一个日期,没有时间: new Temporal.PlainDate(2024, 7, 26);Temporal.PlainDate.from('2024-07-26');// both return a PlainDate object that represents 26th July 2024
PlainTime()作为 PlainDate()的补充,我们可以使用它来创建一个没有日期的时间,使用.PlainTime(): new Temporal.PlainTime(20, 24, 0);Temporal.PlainTime.from('20:24:00');// both return a PlainTime object of 20:24
PlainMonthDay()PlainMonthDay()与 类似PlainDate,但它只返回月份和日期,没有年份信息(对于每年在同一天重复出现的日期很有用,例如圣诞节和情人节): const valentinesDay = Temporal.PlainMonthDay.from({ month: 2, day: 14 });
PlainYearMonth()同样,还有PlainYearMonth只返回年份和月份(对于表示一年中的整个月份很有用): const march = Temporal.PlainYearMonth.from({ month: 3, year: 2024 });
计算可以使用 Temporal 对象完成许多计算。您可以向日期对象添加和减去各种时间单位:
const today = Temporal.Now.plainDateISO();const lastWeek = today.subtract({ days: 7});const nextWeek = today.add({ days: 7 });
和until方法since可让您了解距某个特定日期或自该日期发生以来的时间。例如,以下代码将告诉您距离巴黎奥运会还有多少天: olympics.until().daysvalentinesDay.since().hours
这些方法返回一个Temporal.Duration对象,该对象可用于测量具有多种不同单位和舍入选项的时间量。 附加功能您可以从 Date 对象中提取年、月、日,并从 Time 对象中提取时、分、秒、毫秒、微秒和纳秒(微秒和纳秒在当前 DateTime 对象中不可用)。例如: olympics.hour;<< 20
还有其他属性,例如dayOfWeek(返回1星期一和7星期日)、daysInMonth(返回28, 29,30或31取决于月份) 和daysinYear(返回365或366取决于闰年)。 Temporal日期对象还有一个compare方法,可用于使用各种排序算法对日期进行排序。 Temporal 目前是第 3 阶段提案,浏览器供应商正在实施该提案,因此似乎它的时机已经到来(双关语)。 Pipe Operator在2022年JS现状调查在中,“您认为 JavaScript 目前缺少什么?”的第六个热门答案 是一名管道操作员。
管道运算符是函数式语言中的一项标准功能,它允许您将值从一个函数“管道”到另一个函数,前一个函数的输出用作下一个函数的输入(类似于 Fetch API 传递它从一个承诺返回到下一个承诺的任何数据)。 例如,假设我们想要连续将三个函数应用于一个字符串: - 连接字符串“Listen up!” 到原始字符串的开头。
- 将三个感叹号连接到字符串的末尾。
- 将所有文本设为大写。
这三个函数可以写成如下: const exclaim = string => string + "!!!"const listen = string => "Listen up! " + stringconst uppercase = string => string.toUpperCase()
这三个函数可以通过将它们全部嵌套在一起来应用,如下所示: const text = "Hello World"uppercase(exclaim(listen(text)))<< "LISTEN UP! HELLO WORLD!!!"
但是像这样深度嵌套多个函数调用可能会很快变得混乱,特别是因为text作为参数传递的值 ( ) 最终深深嵌入到表达式中,使其难以识别。 函数嵌套的另一个问题是函数的应用顺序是从后到前的,即最里面的函数首先被应用。因此,在这种情况下,listengets 应用于 的原始值text,然后是,最后将应用exclaim最外层函数。uppercase特别是对于大型且复杂的函数,这变得很难且不直观。 另一种方法是使用像这样的函数链:
const text = "Hello World"text.listen().exclaim().uppercase()
这解决了嵌套函数的很多问题。传递的参数位于开头,每个函数按照其应用的顺序出现,因此listen()首先应用,exclaim()然后uppercase()。 不幸的是,这个例子不起作用,因为 ,listen和exclaim函数uppercase不是该类的方法String。他们可以通过猴子修补类来添加String,但这作为一种技术通常不受欢迎。 这意味着,虽然链接看起来比函数嵌套好得多,但它实际上只能与内置函数一起使用(就像数组方法经常使用的那样)。 管道结合了链接的易用性,并且能够将其与任何函数一起使用。根据当前的提案,上面的示例将如下所示: text |> listen(%) |> exclaim(%) |> uppercase(%)
令牌%是一个占位符,用于表示前一个函数的输出值,尽管该%字符很可能在正式版本中被其他字符替换。这允许在管道中使用接受多个参数的函数。 管道结合了链接的便利性,但可以与您编写的任何自定义函数一起使用。唯一的条件是您需要确保一个函数的输出类型与链中下一个函数的输入类型匹配。 管道传输最适合只接受从任何先前函数的返回值管道传输的单个参数的柯里化函数它使函数式编程变得更加容易,因为小型的构建块函数可以链接在一起以形成更复杂的复合函数。它还使得部分应用更容易实现。 尽管很受欢迎,但管道运营商一直在努力推进该过程的第二阶段。这是由于对如何表达符号的分歧以及对内存性能及其如何与await. 不过,委员会似乎正在慢慢达成某种协议,因此希望管道运营商能够迅速完成各个阶段并在今年露面。 值得庆幸的是,管道运算符已经在Babel 7.15版本中实现了。 就我个人而言,我们希望管道运算符能够在今年实现并推出,因为它将真正有助于提高 JavaScript 作为一种严肃的函数式编程语言的资格。 Record和元组Record和Tuple提案旨在将不可变的数据结构引入 JavaScript。 元组类似于数组(值的有序列表),但它们是深度不可变的。这意味着元组中的每个值必须是原始值或另一个Record或元组(不是数组或对象,因为它们在 JavaScript 中是可变的)。 元组的创建方式与数组文字类似,但#前面有一个前导哈希符号 ( ): const heroes = #["Batman", "Superman", "Wonder Woman"]
一旦创建,就不能添加其他值,也不能删除任何值。这些值也无法更改。 Record类似于对象(键值对的集合),但它们也是深度不可变的。它们的创建方式与对象类似 - 但与元组相同,它们以前导哈希开头: const traitors = #{ diane: false, paul: true, zac: false, harry: true}
记录仍将使用点符号来访问属性和方法: traitors.paul<< true
数组使用的方括号表示法也可以用于元组: heroes[1]<< "Superman"
但由于它们是不可变的,因此您无法更新任何属性: traitors.paul = false<< Errorheroes[1] = "Supergirl"<< Error
元组和记录的不变性意味着您将能够使用===运算符轻松比较它们: heroes === #["Batman", "Superman", "Wonder Woman"];<< true
需要注意的一件事是,在考虑记录的相等性时,属性的顺序并不重要: traitors === #{ ross: false, zac: false, paul: true, harry: true};// still true, even though the order of people has changed<< true
不过,顺序对于元组来说确实很重要,因为它们是有序的数据列表: heroes === #["Wonder Woman", "Batman", "Superman"];<< false
此页面有一个带有现场游乐场的方便教程,因此您可以习惯记录和元组的工作方式。 正则表达式 /v 标志从版本 3 开始,正则表达式就被纳入 JavaScript 中,并且自那时以来已经有了许多改进(例如uES2015 中使用标志的 Unicode 支持)。标志v提案 旨在完成u标志所做的所有事情,但它增加了一些额外的好处,我们将在下面的示例中看到。 简单地说,实现该v标志需要/v在正则表达式的末尾添加 a 。 例如,可以使用以下代码来测试某个字符是否是表情符号: const isEmoji = /^\p{RGI_Emoji}$/v;isEmoji.test(" |