关于ECMAScript 2016, 2017, 和2018中新增功能(摘抄)

时间:2024-04-30 22:35:50

ECMAScript 2016

1. Array.prototype.includes

includes是数组上的简单实例方法,并有助于轻松查找某个项是否在Array中(包括NaN不像indexOf

const arr = [ 1, 2, 3, 4, NaN];
// es2016不使用
if(arr.indexOf(3) >= 0){
 console.log(true);
}
//使用
if(arr.includes(3)){
 console.log(true);
}
//ps: 注意 indexOf 是不支持查找NaN的
arr.includes(NaN) // true
arr.indexOf(NaN) // -1 (indexOf 不支持 NaN)
(注:想要命名的JavaScript规范contains,但这显然已被Mootools使用,因此他们使用了includes。)
2. 指数运算符

数学运算如加法和减法分别有 + 和 - 等运算符。与他们类似,** 运算符通常用于指数运算。在ECMAScript 2016中,引入了 ** 而不是Math.pow。

// 不使用
Math.pow(7,2) //49
//使用
7**2 //49

ECMAScript 2017

1. Object.values()

Object.value()是一个与Object.keys()类似的新函数,但会返回Object自身属性的所有值,排除原型链中的任何值。

const cars = { 'BMW': 3, 'Tesla': 2, 'Toyota': 1 };
//ES2015
//ES2017 不使用
const vals = Object.keys(cars).map(key => cars[key]);
console.log(vals); //[3, 2, 1]
//ES2017 and 未来
//使用
const values = Object.values(cars);
console.log(values); // [3, 2, 1]
2. Object.entries()

Object.entries()Object.keys相关,但不是仅返回keys,而是以数组方式返回keys和values。这使得像循环中使用对象或将对象转换为Maps这样的事情变得非常简单。

例 1:

const cars = { 'BMW': 3, 'Tesla': 2, 'Toyota': 1 };
// ES5.1
//而不是提取键然后再循环
Object.keys(cars).forEarch(function(key) {
   console.log('key: ' + key + 'value: ' + cars[key]);
})
//ES2017 (ES8)
//使用 Object.entries
for(let [key value] of Object.entries(cars)) {
   console.log(`key: ${key} value: ${value}`);
}
例 2:
const cars = { 'BMW': 3, 'Tesla': 2, 'Toyota': 1 };
//ES2015
//不使用
//获取对象键,然后添加每个项目以在循环中映射
const maps = new Map();
Object.keys(cars).forEarch(key => {
   maps.set(key, cars[key]);
})
console.log(map1) // Map { 'BMW' => 3, 'Tesla' => 2, 'Toyota' => 1}
//ES2017 and 以后
//使用
const map = new Map(Object.entries(cars));
console.log(map) //Map { 'BMW' => 3, 'Tesla' => 2, 'Toyota' => 1}

ECMAScript 2018

1. 共享内存和原子 (Shared memory and atomics)

这是一个巨大的,非常先进的功能,是对JS引擎的核心增强。

主要思想是为JavaScript提供某种多线程功能,以便JS开发人员可以编写高性能,通过允许自己管理内存而不是让JS引擎管理内存来实现并发程序。

这是通过一种名为SharedArrayBuffer的新型全局对象来完成的,它基本上将数据存储在共享内存空间中.所以这个数据可以在主JS线程和网络工作者线程之间共享。

到现在为止,如果我们想要在主JS线程和Web工作者之间共享数据,我们必须复制数据并使用postMessage将其发送到其他线程。就这样子!

您只需使用SharedArrayBuffer,主线程和多个Web工作线程即可访问数据。

但在线程之间共享内存可能会导致竞争状况。为了避免竞争条件,引入了“Atomics”全局对象。当一个线程正在使用它的数据时,Atomics提供了各种方法来锁定共享内存。它还提供了安全地更新共享内存中的数据的方法。

建议通过某个库使用此功能,但现在没有构建在此功能之上的库。

如果您有兴趣,推荐阅读:

  1. From Workers to Shared Memory — lucasfcosta

  2. A cartoon intro to SharedArrayBuffers — Lin Clark

  3. Shared memory and atomics — Dr. Axel Rauschmayer

2. 标记模板字面限制已删除(模板字符串)

首先,我们需要澄清一下“Tagged Template literal”是什么,这样我们可以更好地理解这个特性。

在ES2015+中,有一项称为标记模板文字的功能,允许开发人员自定义如何插入字符串。例如,以标准方式插入字符串,如下所示

//标准字符串插值 
const firstName = 'Raja';
const greetings = `Hello ${firstName}!`;
console.log(greetings); // "Hello Raja!"

在标记字面量中,可以编写一个函数来接收字符串文字的硬编码部分,例如['Hello','!']和替换变量,例如['Raja'],作为参数写入自定义函数(例如greet),然后从该自定义函数中返回所需的任何内容。

下面的例子显示我们的自定义“Tag”函数greet“Good Morning!”,“Good afternoon,”等日子的时间,依此类推,取决于字符串文字的一天中的时间,并返回一个自定义字符串。

// "标记”函数返回一个自定义字符串文字.
// 在这个例子中,greet调用timeGreet()来追加Good
// Morning/Afternoon/Evening 视当天的时间而定.
function greet(hardCodedPartsArray, ...replacementPartsArray) {
console.log(hardCodedPartsArray); //[ 'Hello ', '!' ]
console.log(replacementPartsArray); //[ 'Raja' ]
let str = '';
hardCodedPartsArray.forEach((string, i) => {
 if (i < replacementPartsArray.length) {
  str += `${string} ${replacementPartsArray[i] || ''}`;
 } else {
  str += `${string} ${timeGreet()}`; //<-- 插入 Good morning/afternoon/evening here
 }
});
return str;
}
//用法
const firstName = 'Raja';
const greetings = greet`Hello ${firstName}!`; //