20多个小案例带您回到ES10的新功能(总结)
尽管ES10没有ES6那么多新功能,但ES10仍有一些有用的功能。本文通过简单的例子介绍了ES10的新特性。这样不用看太多官方解释就能快速理解。
ES10的新功能主要如下:
数组方法:flat和flatMap Object.fromEntries字符串方法:description属性try {} catch {} //of trimStart和trimEnd Symbol catch的参数可以省略JSON ECMAScript(使ECMAScript与所有JSON支持的文本兼容)、格式良好的JSON.stringify()、稳定的Array.prototype.sort()修改后的Function.toString BigInt是第七个原始类型,动态导入标准化的globalThis对象1。array.flat () array.flatmap。
Array.flat()方法根据指定的深度递归遍历数组,并将所有元素与遍历的子数组中的元素合并成一个新数组返回。
Array.flatMap()方法首先用映射函数映射每个元素,然后将结果压缩成一个新的数组。它几乎与深度值为1的map和flat相同,但是flatMap在组合成一种方法时通常会更高效一点。
例1:
Array.flat()
让multi=[1,2,3,[4,5,6,[7,8,9,[10,11,12]]]];multi . flat();//[1,2,3,4,5,6,Array(4)]. multi . flat()。flat();//[1,2,3,4,5,6,7,8,9,Array(3)]. multi . flat()。平面()。flat();//[1,2,3,4,5,6,7,8,9,10,11,12]multi . flat(Infinity);//[1,2,3,4,5,6,7,8,9,10,11,12]Array.flatMap()
让数组=[1,2,3,4,5];array.map(x=[x,x * 2]);现在数组的结果:
[数组(2),数组(2),数组(2)] 0: (2) [1,2] 1: (2) [2,4] 2: (2) [3,6]使用flatMap:
array.flatMap(v=[v,v * 2]);[1,2,2,4,3,6,4,8,5,10]综合示例:
2.Object.fromEntries()
方法将键值对列表转换成一个对象。
例1:
让obj={苹果: 10,橘子: 20,香蕉: 30 };让条目=对象条目(obj);条目;(3) [Array(2),Array(2),Array(2)] 0: (2) ['apple ',10] 1: (2) ['orange ',20] 2: (2) ['banana ',30]let from entries=object . from entries(entries);{苹果: 10,橘子: 20,香蕉: 30}案例二:
3.String.protype.matchAll
早期的一个问题是正则表达式“match all”怎么写。
最好的答案是String.match与正则表达式和/g一起使用,或者RegExp.exec与/g一起使用,或者RegExp.test与/g一起使用
让我们首先看看旧规范是如何工作的。
String.match使用字符串参数只返回第一个匹配项:
让字符串=' Hellolet matches=string . match(' l ');console.log(匹配[0]);//“l”结果是单个“l”(注意:匹配项存储在匹配项[0]中,而不是匹配项中)
使用string.match和regex参数也是如此:
使用正则表达式/l/查找字符串“hello”中的“l”字符:
让字符串=' Hellolet matches=string . match(/l/);console.log(匹配[0]);//'l' add /g mix
让字符串=' Hello让ret=string . match(/l/g);//(2) ["l "、" l "];那么为什么要使用新的matchAll方法呢?在解决这个问题之前,我们先来看看捕获组。
正则表达式捕获组
在正则表达式中捕获组只从()括号中提取一个模式,您可以使用/regex/。exec(字符串)和string.match来捕获组。
常规捕获组是通过在模式中包装模式来创建的,但是要在结果对象上创建group属性,它是:(?名称模式).
要创建新的组名,只需追加?因此,模式匹配将变成group.name并附加到匹配对象。以下是一个例子:
字符串样本匹配:
match . group . color和match . group . bird就是在这里创建的:
const string='黑色*乌鸦石灰*鹦鹉白色*海鸥';const regex=/(?颜色。*?)\*(?bird[a-z0-9])/g;while(match=regex . exec(string)){ let value=match[0];让index=match.index让input=match.inputconsole.log(`${value}位于${index}处,带有' ${input} ' `);console . log(match . groups . color);console . log(match . groups . bird);}需要多次调用regex.exec方法来遍历整个搜索结果集。什么时候?在每次迭代中调用exec,显示下一个结果(它不会立即返回所有匹配项),因此使用while循环。
输出如下:
黑色*乌鸦在0与'黑色*乌鸦石灰*鹦鹉白色*海鸥'黑色乌鸦石灰*鹦鹉在11与'黑色*乌鸦石灰*鹦鹉白色*海鸥'石灰鹦鹉白色*海鸥在23与'黑色*乌鸦石灰*鹦鹉白色*海鸥'白色海鸥
但奇怪的是:
如果从该正则表达式中删除/g,将总是在第一个结果上创建一个无限循环。这在过去是一种巨大的痛苦。想象一下,当您从数据库接收到一个正则表达式时,您不确定它的末尾是否有/g,所以您必须首先检查它。很好的理由。matchAll()
当与捕获组一起使用时,它会更优雅,捕获组只是使用()提取模式的正则表达式的一部分。它返回一个迭代器而不是数组,迭代器本身是有用的。迭代器可以使用扩展运算符(…)转换为数组。它避免了带有/g标志的正则表达式,并且在从数据库或外部源检索未知正则表达式并将它们与过时的RegEx对象一起使用时非常有用。用RegEx对象创建的正则表达式不能用点(.)链接。)运算符。高级: RegEx对象改变了内部。lastindex属性,用于跟踪最后一个匹配位置,在复杂情况下可能会导致严重损坏。怎么会?matchAll()工作?
让我们尝试匹配单词hello中字母e和l的所有实例,因为迭代器被返回,我们可以使用for…of循环遍历它:
//匹配字母“e”或“l”的所有出现,让迭代器=“hello”。match all(/[El]/);for(迭代器的常量匹配)console . log(match);这一次,您可以跳过/g,而。matchall方法不需要它。结果如下:
['e ',索引: 1,输入:' hello']//迭代1 ['l ',索引: 2,输入: ' hello ']//迭代2 ['l ',索引: 3,输入: ' hello ']//。
const string='黑色*乌鸦石灰*鹦鹉白色*海鸥';const regex=/(?颜色。*?)\*(?bird[a-z0-9])/;for(string . MATCHALL(regex)的常量匹配){ let value=match[0];让index=match.index让input=match.inputconsole.log(`${value}位于${index}处,带有' ${input} ' `);console . log(match . groups . color);console . log(match . groups . bird);}请注意没有/g标志,因为。matchAll()已经包含它,打印如下:
black*raven at 0配' black * ravenlime * parrot white *海鸥' blackravenlime*parrot at 11配' black * raven lime * parrot white *海鸥' limeparrotwhite*海鸥at 23配' black * raven lime * parrot white *海鸥' white海鸥在美学上可能与原始正则表达式非常相似,它实现了while循环。但是如前所述,由于上面提到的许多原因,这是一个更好的方法,移除/g不会导致无限循环。
综合示例:
4.String.trimStart()和String.trimEnd()
TrimStart():删除字符串的前导空格。
TrimEnd():删除字符串末尾的空格。
例1:
让问候语=周围的空间;hello . trimend();//“周围空间”;hello . trim start();//“周围空间”;例2:
5.符号.描述
描述是一个只读属性,它返回符号对象的可选描述字符串。
例1:
让我的符号=我的符号;让symObj=Symbol(mySymbol);symObj//Symbol(我的符号)symObj.description//“我的符号”案例2:
6.6.catch的参数可以省略
过去,try/catch语句中的catch语句需要一个变量。Try/catch语句有助于捕获终端级错误:
尝试{ //调用不存在的函数undefined _ Function undefined _ Function(‘我在尝试’);}catch(错误){ //如果上面try中的语句失败,则显示错误。log(错误);//undefined _ function未定义}在某些情况下,所需的错误变量未使用:
尝试{ JSON . parse(text);//-如果“文本未定义”返回true,此操作将失败;-即使有一个{ catch(redundancy _ sometes)也可以无错误退出-这使得错误变量冗余{ return false}在ES10中,捕获错误的变量是可选的,现在可以跳过错误变量:
例1:
尝试{ JSON . parse(text);返回真;} catch { return false}案例2:
7.JSON ECMAScript
什么是JSON超集?请记住,这个符号可以解释提案JSON ECMAScript,使得ECMAScript与所有JSON支持的文本兼容。ECMAScript曾经在标准JSON.parse中声明JSON确实是它的子集,但是因为JSON内容通常可以包含U 2028行分隔符和U 2029段分隔符,所以ECMAScript不能。
草案旨在解决这个问题。在此之前,如果使用JSON.parse()执行带有上述特殊字符的字符串,将只会收到一条语法错误的错误消息。草案也是向后兼容的,它对用户的唯一影响就是保持原样,也就是说,在暂时不支持特殊字符解析的运行环境中,保持SyntaxError报告错误。
8.格式良好的JSON.stringify()
此更新修复了字符U D800到U DFFF的处理,有时会输入JSON字符串。这可能是一个问题,因为JSON.stringify可能会将这些数字格式化为没有UTF-8字符的值,但是JSON格式需要UTF-8编码。
解析方法使用格式良好的JSON字符串,例如:
{“prop 1”: 1,“prop 2”: 2 } ';//一个格式良好的JSON格式字符串注意,要创建一个具有正确JSON格式的字符串,绝对需要在属性名周围加上双引号。缺少引号或任何其他类型的引号都不会生成格式良好的JSON。
{ "prop1" : 1,' meth ' :()={ } } ';//Not JSON格式stringJSON字符串格式不同于Object Literal,后者看起来几乎一样,但是可以使用任何类型的引号将属性名称括起来,也可以包含方法(JSON格式不允许方法):
let object _ literal={ property : 1,meth :()={ } };不管怎样,一切似乎都很好。第一个例子似乎是兼容的。但它们也是简单的例子,在大多数情况下都可以顺利工作!
U 2028和U 2029字符
问题是ES10之前的EcmaScript实际上并不完全支持JSON格式。在ES10之前的时代,不接受非转义行分隔符U 2028和段落分隔符U 2029字符:
对于ud800和udfff之间的所有字符也是如此
如果这些字符偷偷进入JSON格式的字符串(假设它们来自数据库记录),您可能会花几个小时试图弄清楚为什么程序的其余部分会产生解析错误。
因此,如果您传递像eval "console.log(' hello ')这样的字符串,它将执行JS语句(通过尝试将字符串转换为实际代码),这类似于JSON.parse处理您的JSON字符串的方式。
ES10建议的解决方案是将不成对的代理代码点表示为JSON转义序列,而不是将它们作为单个UTF-16代码单元返回。
9.稳定数组。原型。排序()
V8之前的实现对包含10个以上项目的数组使用了不稳定的快速排序。
一个稳定的排序算法是当两个具有相同键值的对象在排序的输出中以与未排序的输入相同的顺序出现时。但现在已经不是这样了。ES10提供稳定的阵列排序:
var水果=[ { name: 'Apple ',count: 13,},{ name: 'Pear ',count: 12,},{ name: 'Banana ',count: 12,},{ name: '草莓',count: 11,},{ name: 'Cherry ',count: 11,},{ name 3: '黑莓',count 3: 11//创建排序函数:让my _ sort=(a,b)=a . count-b . count;//执行稳定的ES10排序:让sorted=水果. sort(my _ sort);console.log(已排序);控制台输出(项目以相反顺序出现):
例2:
10.新的函数
该函数是一个对象,每个对象都有一个. toString()方法,因为它最初存在于Object.prototype.toString()上。包括函数在内的所有对象都是通过基于原型的类继承从它那里继承的。
这意味着我们以前有funcion.toString()方法。
然而,ES10进一步尝试标准化所有对象和内置函数的字符串表示。以下是各种新案例:
典型示例:
function () { console.log('你好,这里');}.toString();输出:
函数(){ console.log('你好。);}直接在方法名中。toString()
number . Parseint . ToString();function Parsent(){[native code]}绑定上下文:
function () { }。绑定(0)。toString();Function () {[nativecode]}具有内置的可调用函数对象:
symbol . ToString();函数符号(){[nativecode]}动态生成的函数:
函数* () { }。toString();函数*(){ }原型. toString
function . prototype . ToString . call({ });函数.原型. toString要求“这”是一个函数
11.BigInt-任意精度整数
BigInt是第七种基本类型。
BigInt是一个任意精度的整数。这意味着变量现在可以表示数字,而不仅仅是9007199254740999。
const b=1n//追加n创建BigInt。过去,不支持大于9007199254740992的整数值。如果超过,该值将被锁定为MAX_SAFE_INTEGER 1:
常量限制=数字。MAX _ SAFE _ INTEGER9007199254740991限制1;9007199254740992限制2;9007199254740992-max _ safe _ integer 1 excededconst较大=9007199254740991n9007199254740991整数=big int(9007199254740991);//初始化为number9007199254740991 const same=bigint(' 9007199254740991 ');//初始化为'string'9007199254740991n
12.动态导入
动态导入返回所请求模块的模块命名空间对象的承诺。因此,异步/等待可以一起使用。
例1:
element . addeventlistener(' click ',async()={ const module=wait import(`)。/API-scripts/button-click . js `);module . ClickEvent();})案例2:
13.标准化全局这个对象
在ES10之前,globalThis没有标准化,通常的项目可以通过以下方式兼容不同的平台:
var GetGlobal=function(){ if(type of self!==' undefined '){ return self;} if(窗口类型!=='undefined') {返回窗口;} if (typeof global!=='undefined') {返回全局;}抛出新错误('无法定位全局对象');};但即使这样也不总是奏效。因此,ES10增加了globalThis对象,从此可以在任何平台上访问全局范围:
但即使这样也不总是奏效。因此,ES10增加了globalThis对象,从此可以在任何平台上访问全局范围:
摘要
JS是一种动态语言,非常有利于web开发。自2015年ES6出现以来,JS经历了一个动态的演变。在本文中,我们回顾了ES10(2019)中出现的特性,并介绍了一些将在ES11(2020)中保持稳定的特性,因为它们处于状态3,并且很可能在下一个版本中实现标准化。
虽然这些特性中的许多对于Web应用程序的开发来说可能不是必需的,但是一些特性可以规范我们过去通过技巧或大量冗长来实现的代码。
代码部署后可能存在的bug无法实时获知。为了事后解决这些bug,需要花费大量时间调试日志。顺便推荐一个不错的bug监控工具Fundebug。
原文:https://dev。to/carlillo/12-es10-12中的功能-简单示例-2cbn
以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。
版权声明:20多个小案例带您回到ES10的新功能(总结)是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。