今年,ecmascript 2019(简称es2019)将会发布。 新功能包括object.fromentries(),trimstart(),trimend(),flat(),flatmap(),symbol对象的description属性,可选的catch绑定等。
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 ";// es2019console.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 9arr.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); // => foosym = symbol();console.log(sym.description); // => undefined// create a global symbolsym = 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 。
更多相关知识请关注javascript视频教程栏目
以上就是5个es10的新特性的详细内容。
