浅谈目前可以使用ES10的5个新特性


Posted in Javascript onJune 25, 2019

ECMAScript 2015,也称为ES6,是一个花了6年时间完成的主要版本。从那时起,负责ECMAScript标准开发的技术委员会39 (TC39)每年都会发布该标准的新版本。这个年度发布周期简化了这个过程,并使新特性快速可用,JavaScript社区对此表示欢迎。

今年,ECMAScript 2019(简称ES2019)将会发布。 新功能包括Object.fromEntries(),trimStart(),trimEnd(),flat(),flatMap(),symbol对象的description属性,可选的catch绑定等。

好消息是这些功能已经在最新版本的Firefox和Chrome中实现,并且它们也可以被转换,以便旧版浏览器能够处理它们。

1. Object.fromEntries()

在JavaScript中,将数据从一种格式转换为另一种格式非常常见。 为了便于将对象转换为数组,ES2017引入了Object.entrie()方法。 此方法将对象作为参数,并以[key,value]的形式返回对象自己的可枚举字符串键控属性对的数组。 例如:

const obj = {one: 1, two: 2, three: 3};

console.log(Object.entries(obj));  
// => [["one", 1], ["two", 2], ["three", 3]]

但是如果我们想要做相反的事情并将键值对列表转换为对象呢? 某些编程语言(如Python)为此提供了dict()函数。 在Underscore.js和Lodash中还有_.fromPairs函数。

ES2019引入Object.fromEntries()方法为JavaScript带来类似的功能, 此静态方法允许你轻松地将键值对列表转换为对象:

const myArray = [['one', 1], ['two', 2], ['three', 3]];
const obj = Object.fromEntries(myArray);

console.log(obj);  // => {one: 1, two: 2, three: 3}

如你所见,Object.fromEntries()与Object.entries()所做的事情正好相反。 虽然以前可以实现Object.fromEntries()相同的功能,但它实现方式有些复杂:

const myArray = [['one', 1], ['two', 2], ['three', 3]];
const Array.from(myArray).reduce((acc, [key, val]) 
=> Object.assign(acc, {[key]: val}), {})

console.log(obj);  // => {one: 1, two: 2, three: 3}

请记住,传递给Object.fromEntries()的参数可以是实现可迭代协议的任何对象,只要它返回一个两元素,类似于数组的对象即可。

例如,在以下代码中,Object.fromEntries() 将Map对象作为参数,并创建一个新对象,其键和对应值由Map中的对给出:

const map = new Map();
map.set('one', 1);
map.set('two', 2);

const obj = Object.fromEntries(map);

console.log(obj);  // => {one: 1, two: 2}

Object.fromEntries() 方法对于转换对象也非常有用,思考以下代码:

const obj = {a: 4, b: 9, c: 16};

// 将对象转换为数组
const arr = Object.entries(obj);

// 计算数字的平方根
const map = arr.map(([key, val]) => [key, Math.sqrt(val)]);

// 将数组转换回对象
const obj2 = Object.fromEntries(map);

console.log(obj2); // => {a: 2, b: 3, c: 4}

上述代码将对象中的值转换为其平方根。 为此,它首先将对象转换为数组,然后使用map()方法获取数组中值的平方根,结果是可以转换回对象的数组。

使用Object.fromEntries()的另一种情况是处理URL的查询字符串,如本例所示

const paramsString = 'param1=foo¶m2=baz';
const searchParams = new URLSearchParams(paramsString);

Object.fromEntries(searchParams);  // => {param1: "foo", param2: "baz"}

此代码中,查询字符串将传递给 URLSearchParams()构造函数。 然后将返回值(即URLSearchParams对象实例)传递给Object.fromEntries() 方法,结果是一个包含每个参数作为属性的对象。

Object.fromEntries() 方法目前是第4阶段提案,这意味着它已准备好包含在ES2019标准中。

2. trimStart() and trimEnd()

trimStart()和trimEnd()方法在实现与trimLeft()和trimRight()相同。这些方法目前处于第4阶段,将被添加到规范中,以便与padStart()和padEnd()保持一致,来看一些例子:

const str = "  string  ";

// es2019
console.log(str.trimStart());  // => "string  "
console.log(str.trimEnd());   // => "  string"

// 相同结果
console.log(str.trimLeft());   // => "string  "
console.log(str.trimRight());  // => "  string"

对于Web兼容性,trimLeft() 和trimRight() 将保留为trimStart() 和trimEnd() 的别名。

3. flat() and flatMap()

flat() 方法可以将多维数组展平成一维数组

const arr = ['a', 'b', ['c', 'd']];
const flattened = arr.flat();

console.log(flattened);  // => ["a", "b", "c", "d"]

以前,我们经常使用reduce()或concat()来展平多维数组:

const arr = ['a', 'b', ['c', 'd']];
const flattend = [].concat.apply([], arr);

// or
// const flattened = [].concat(...arr);

console.log(flattened);  // => ["a", "b", "c", "d"]

请注意,如果提供的数组中有空值,它们会被丢弃:

const arr = ['a', , , 'b', ['c', 'd']];
const flattened = arr.flat();

console.log(flattened);  // => ["a", "b", "c", "d"]

flat() 还接受一个可选参数,该参数指定嵌套数组应该被展平的级别数。 如果未提供参数,则将使用默认值1:

const arr = [10, [20, [30]]];

console.log(arr.flat());   // => [10, 20, [30]]
console.log(arr.flat(1));  // => [10, 20, [30]]
console.log(arr.flat(2));  // => [10, 20, 30]

flatMap() 方法将map()和flat()组合成一个方法。 它首先使用提供的函数的返回值创建一个新数组,然后连接该数组的所有子数组元素。 来个例子:

const arr = [4.25, 19.99, 25.5];

console.log(arr.map(value => [Math.round(value)]));  
// => [[4], [20], [26]]

console.log(arr.flatMap(value => [Math.round(value)]));  
// => [4, 20, 26]

数组将被展平的深度级别为1.如果要从结果中删除项目,只需返回一个空数组:

const arr = [[7.1], [8.1], [9.1], [10.1], [11.1]];

// do not include items bigger than 9
arr.flatMap(value => {
 if (value >= 10) {
  return [];
 } else {
  return Math.round(value);
 }
}); 

// returns:
// => [7, 8, 9]

除了正在处理的当前元素外,回调函数还将接收元素的索引和对数组本身的引用。flat()和flatMap()方法目前处于第4阶段。

4.Symbol 对象的 description 属性

在创建Symbol时,可以为调试目的向其添加description (描述)。有时候,能够直接访问代码中的description 是很有用的。

ES2019 中为Symbol对象添加了只读属性 description ,该对象返回包含Symbol描述的字符串。

let sym = Symbol('foo');
console.log(sym.description);  // => foo

sym = Symbol();
console.log(sym.description);  // => undefined

// create a global symbol
sym = Symbol.for('bar');
console.log(sym.description);  // => bar

5.可选的 catch

try catch 语句中的catch有时候并没有用,思考下面代码:

try {
 // 使用浏览器可能尚未实现的功能
} catch (unused) {
 // 这里回调函数中已经帮我们处理好的错误
}

此代码中的catch回调的信息并没有用处。 但这样写是为了避免SyntaxError错误。 ES2019可以省略catch周围的括号:

try {
 // ...
} catch {
 // ....
}

另外:ES2020 的 String.prototype.matchAll

matchAll() 方法是ES2020 第4阶段提议,它针对正则表达式返回所有匹配(包括捕获组)的迭代器对象。

为了与match()方法保持一致,TC39 选择了“matchAll”而不是其他建议的名称,例如 “matches” 或 Ruby的 “scan”。看个简单的例子:

const re = /(Dr\. )\w+/g;
const str = 'Dr. Smith and Dr. Anderson';
const matches = str.matchAll(re);

for (const match of matches) {
 console.log(match);
}

// logs:
// => ["Dr. Smith", "Dr. ", index: 0, input: "Dr. Smith and Dr. Anderson", groups: undefined]
// => ["Dr. Anderson", "Dr. ", index: 14, input: "Dr. Smith and Dr. Anderson", groups: undefined]

此正则表达式中的捕获组匹配字符“Dr”,后跟一个点和一个空格。\w+ 匹配任何单词字符一次或多次。 并且g标志指示引擎在整个字符串中搜索模式。

之前,必须在循环中使用exec()方法来实现相同的结果,这不是非常有效:

const re = /(Dr\.) \w+/g;
const str = 'Dr. Smith and Dr. Anderson';
let matches;

while ((matches = re.exec(str)) !== null) {
 console.log(matches);
}

// logs:
// => ["Dr. Smith", "Dr.", index: 0, input: "Dr. Smith and Dr. Anderson", groups: undefined]
// => ["Dr. Anderson", "Dr.", index: 14, input: "Dr. Smith and Dr. Anderson", groups: undefined]

重要的是要注意尽管match() 方法可以与全局标志g一起使用来访问所有匹配,但它不提供匹配的捕获组或索引位置。 比较以下代码:

const re = /page (\d+)/g;
const str = 'page 2 and page 10';

console.log(str.match(re));  
// => ["page 2", "page 10"]

console.log(...str.matchAll(re)); 
// => ["page 2", "2", index: 0, input: "page 2 and page 10", groups: undefined] 
// => ["page 10", "10", index: 11, input: "page 2 and page 10", groups: undefined]

总结

在这篇文章中,我们仔细研究了 ES2019 中引入的几个关键特性,包括Object.fromEntries(),trimStart(), trimEnd(), flat(), flatMap(),symbol 对象的description 属性以及可选的catch 。

尽管一些浏览器还没有完全实现这些特性,但可以使用Babel和其他JavaScript转换器,仍然可以在项目中使用它们。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
如何让页面加载完成后执行js
Jun 26 Javascript
GridView中获取被点击行中的DropDownList和TextBox中的值
Jul 18 Javascript
JS实现程序暂停与继续功能代码解读
Oct 10 Javascript
jquery等待效果示例
May 01 Javascript
javascript下拉框选项单击事件的例子分享
Mar 04 Javascript
VUEJS实战之利用laypage插件实现分页(3)
Jun 13 Javascript
微信小程序 动态的设置图片的高度和宽度详解及实例代码
Feb 24 Javascript
AngularJS实现tab选项卡的方法详解
Jul 05 Javascript
仿ElementUI实现一个Form表单的实现代码
Apr 23 Javascript
详解如何在vue项目中使用layui框架及采坑
May 05 Javascript
mapboxgl区划标签避让不遮盖实现的代码详解
Jul 01 Javascript
详解Vue2的diff算法
Jan 06 Vue.js
vue 移动端注入骨架屏的配置方法
Jun 25 #Javascript
基于vue+axios+lrz.js微信端图片压缩上传方法
Jun 25 #Javascript
新手快速入门微信小程序组件库 iView Weapp
Jun 24 #Javascript
前端Vue项目详解--初始化及导航栏
Jun 24 #Javascript
微信小程序调用天气接口并且渲染在页面过程详解
Jun 24 #Javascript
微信小程序-可移动菜单的实现过程详解
Jun 24 #Javascript
webpack自动打包和热更新的实现方法
Jun 24 #Javascript
You might like
《被神捡到的男人》动画化计划进行中!
2020/03/06 日漫
php下关于中英数字混排的字符串分割问题
2010/04/06 PHP
Laravel框架使用技巧之使用url()全局函数返回前一个页面的地址方法详解
2020/04/06 PHP
JavaScript操作XML实例代码(获取新闻标题并分页,并分页)
2010/05/25 Javascript
分享一个自定义的console类 让你不再纠结JS中的调试代码的兼容
2012/04/20 Javascript
js拖动div 当鼠标移动时整个div也相应的移动
2013/11/21 Javascript
jquery使用$(element).is()来判断获取的tagName
2014/08/24 Javascript
Javascript核心读书有感之表达式和运算符
2015/02/11 Javascript
JQuery radio(单选按钮)操作方法汇总
2015/04/15 Javascript
JavaScript实现的冒泡排序法及统计相邻数交换次数示例
2017/04/26 Javascript
jQuery EasyUI结合zTree树形结构制作web页面
2017/09/01 jQuery
vue组件横向树实现代码
2018/08/02 Javascript
Vue路由 重定向和别名的区别说明
2020/09/09 Javascript
[04:13]2014DOTA2国际邀请赛 专访DC目前形势不容乐观
2014/07/12 DOTA
python使用os模块的os.walk遍历文件夹示例
2014/01/27 Python
Python中使用wxPython开发的一个简易笔记本程序实例
2015/02/08 Python
Python之Scrapy爬虫框架安装及简单使用详解
2017/12/22 Python
Python 数据处理库 pandas进阶教程
2018/04/21 Python
Pycharm 设置自定义背景颜色的图文教程
2018/05/23 Python
Python实现重建二叉树的三种方法详解
2018/06/23 Python
解决python selenium3启动不了firefox的问题
2018/10/13 Python
python Tkinter的图片刷新实例
2019/06/14 Python
用Python抢火车票的简单小程序实现解析
2019/08/14 Python
基于Python实现大文件分割和命名脚本过程解析
2019/09/29 Python
如何利用pygame实现简单的五子棋游戏
2019/12/29 Python
PyTorch中permute的用法详解
2019/12/30 Python
Python实现清理微信僵尸粉功能示例【基于itchat模块】
2020/05/29 Python
OpenCV 之按位运算举例解析
2020/06/19 Python
使用HTML5技术开发一个属于自己的超酷颜色选择器
2013/09/22 HTML / CSS
加拿大城市本地限时优惠:Buytopia.ca
2018/09/19 全球购物
VLAN和VPN有什么区别?分别实现在OSI的第几层?
2014/12/23 面试题
优秀大学生职业生涯规划书
2014/02/27 职场文书
大学校务公开实施方案
2014/03/31 职场文书
人事行政经理岗位职责
2014/06/18 职场文书
司法局群众路线教育实践活动整改措施
2014/09/17 职场文书
小学感恩节活动总结
2015/03/24 职场文书