展望ES2019,8个新特性

发表于:2019-02-18

又快到6月份啦,还记得吗,ECMAScript 每年6月都会发布一个版本。

2019到啦,来看看已完成的提案!

新特性 🎉🎉🎉

  • Optional catch binding
  • JSON superset
  • Symbol.prototype.description
  • Function.prototype.toString revision
  • Object.fromEntries
  • JSON.stringify
  • String.prototype.{trimStart,trimEnd}
  • Array.prototype.{flat,flatMap}

哇!既惊动,又兴奋,带来了8个新特性。

来来,都看看新特性长什么样

注: 各别新特性语法在某些厂商浏览器已经实现。

0x01 Optional catch binding

可选的catch圆括号绑定。

该提议对ECMAScript进行了语法更改,允许在不使用catch绑定的情况下省略绑定。这种情况经常发生在诸如:

let parseResult = someFallbackValue;
try {
  parseResult = JSON.parse(potentiallyMalformedJSON);
} catch (e) {

}

有了新语法可以这么写, 省略掉catch圆括号,是不是很nice ?

let parseResult = someFallbackValue;
try {
  parseResult = JSON.parse(potentiallyMalformedJSON);
} catch {

}

0x02 JSON superset

行分隔符(U + 2028)和段分隔符(U + 2029)符号现在允许在字符串文字中,与JSON匹配。 以前,这些符号在字符串文字中被视为行终止符,因此使用它们会导致SyntaxError异常。

0x03 Symbol.prototype.description

目标:

  • 直接公开Symbol的[[Description]]内部插槽,而不是间接通过Symbol.prototype.toString。

以往获取Symbol描述信息是通过这样:

const sym = Symbol('Hello');
const desc = Symbol.prototype.toString.call(sym);
// Symbol(Hello)

现在有了新的语法可以这么写

const sym = Symbol('Hello');
const desc = sym.description
// Hello

0x04 Function.prototype.toString revision

该提案是一个修订版,修改了函数 toString的返回值, 现在toString返回精确的字符串,包括空格和注释。

以往

function App() {/* var */}

App.toString();
// function App() {}

现在

function App() {
  /* var */
  var h = 'hello';
}

App.toString();
// function App() {
//  /* var */
//  var h = 'hello';
// }

0x05 Object.fromEntries

这是一个静态方法,用于将键值对列表转换为对象。它是 Object.entries 的反向。

一个典型的例子

obj = Object.fromEntries([['a', 0], ['b', 1]]);
// { a: 0, b: 1 }

对象到对象的属性转换, 允许使用熟悉的数组操作方法来转换对象:

obj = { abc: 1, def: 2, ghij: 3 };
res = Object.fromEntries(
  Object.entries(obj)
  .filter(([ key, val ]) => key.length === 3)
  .map(([ key, val ]) => [ key, val * 2 ])
);

// res is { 'abc': 2, 'def': 4 }

现有技术 lodash的也提供了对应的方法 fromPairs, 如果你熟悉。

0x06 JSON.stringify

更加友好的 JSON.stringify (修复了对于一些超出范围的 unicode 展示错误的问题。)

如果输入 Unicode 格式但是超出范围的字符,在原先JSON.stringify返回格式错误的Unicode字符串:

JSON.stringify('\uD800');
// → '"�"'

现在实现了一个改变JSON.stringify的第3阶段提案,因此它为其输出转义序列,使其成为有效Unicode(并以UTF-8表示):

JSON.stringify('\uD800');
//  '"\\ud800"'
在 chrome 控制台输出的是 '"\ud800"' ,但只是一个显示值, 真实值为'"\\ud800"'。

JSON.stringify('\uD800') === '"\\ud800"';
//  true

0x07 String.prototype.trimStart / String.prototype.trimEnd

ES5标准化 String.prototype.trim 。所有主要引擎也实施了相应的 trimLefttrimRight 功能-没有任何标准规范。为了与 padStart/ padEnd 我们提出的一致性 trimStarttrimEndtrimLeft/ trimRight 作为Web兼容性所需的别名。

demo:

str = '   hello';
str.trimStart();
// 'hello'          为了看的仔细使用单引号括住

str = 'hello   ';
// 'hello'

0x08 Array.prototype.{flat, flatMap}

flat 方法会递归到指定深度将所有子数组连接,并返回一个新数组。

语法

// depth 可选, 指定嵌套数组中的结构深度,默认值为1
var newArray = arr.flat(depth)

示例:

var arr1 = [1, 2, [3, 4]];
arr1.flat(); 
// [1, 2, 3, 4]

var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]

var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]

flat()方法会移除数组中的空项:

var arr4 = [1, 2, , 4, 5];
arr4.flat();
// [1, 2, 4, 5]

flatMap 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 和 深度值1的 flat 几乎相同,但 flatMap 通常在合并成一种方法的效率稍微高一些

可以理解为 flat + map函数的结合

语法

/**
 * @param {any} currentValue - 当前正在数组中处理的元素
 * @param {Number}  index - 可选的。数组中正在处理的当前元素的索引。
 * @param {Array} array - 可选的。被调用的 map 数组
 * @param {any} thisArg - 可选的。执行 callback 函数时 使用的this 值
 */
var new_array = arr.flatMap(function callback(currentValue[, index[, array]]) {
  // 返回新数组的元素
}[, thisArg])

先来看看例子

var arr1 = [1, 2, 3, 4];

arr1.map(x => [x * 2]); 
// [[2], [4], [6], [8]]

arr1.flatMap(x => [x * 2]);
// [2, 4, 6, 8]

// 只会将 flatMap 中的函数返回的数组 “压平” 一层
arr1.flatMap(x => [[x * 2]]);
// [[2], [4], [6], [8]]

虽然上面的代码使用 map 和 flatMap 好像都可以,但这只能展示如何使用 flatMap。

所以,为了更好的展示 flatMap 的作用,下面我们将包含几句话的数组拆分成单个汉字组成的新数组。

let arr = ["今天天气不错", "", "早上好"]

arr.map(s => s.split(""))
// [["今", "天", "天", "气", "不", "错"],[""],["早", "上", "好"]]

arr.flatMap(s => s.split(''));
// ["今", "天", "天", "气", "不", "错", "", "早", "上", "好"]

总结

新提案每时每刻都会发生变化,了解新动态,只会学到更多,姿势就会有多种多样。

最后我想说,前端真香~

JavaScript
广告