ES7和ES8的了解

es7新特性
Es7在ES6的基础上添加了三项内容:

*求幂运算符 (**)
Array.prototype.includes()方法.
函数作用域中严格模式的变更

Array.prototype.includes( )

includes()的作用,是查找一个值在不在数组里,若在,则返回true,反之返回false

Array.prototype.includes()方法接收两个参数:要搜索的值和搜索的开始索引。当第二个参数被传入时,该方法会从索引处开始往后

搜索(默认索引值为0)。若搜索值在数组中存在则返回true,否则返回false。

includes()方法有一点不同,两个NaN被认为是相等的,即使在NaN === NaN结果是false的情况下。
这一点和indexOf()的行为不同,indexOf()严格使用===判断
includes()还有一个怪异的点需要指出,在判断 +0 与 -0 时,被认为是相同的。
在这一点上indexOf()与includes()的处理结果是一样的,前者同样会返回 +0 的索引值

es8新特性
异步函数(async function)
由于javascript是单线程的
做法通常是通过回调函数实现JavaScript的异步编程
假如存在还有更多的请求操作就会出现多层嵌套代码就会乱成一团 这种情况就被称之为回调函数地狱
于是promise被提出了它将回调函数的嵌套改成了链式调用

promise的最大问题是代码冗余 ,请求任务时一堆的then,也使原来的语义变得很不清楚此时我们可以引入另外一种异步编程的机制:generator

Es8引入了async函数使得异步操作变得更加方便
实例如下:

Async function asyncFunc(params){
    const result1 = await this.login()
    const result2 = await this.getInfo()
}

异步函数存在以下四种使用形式:
函数声明: async function foo() {}
函数表达式: const foo = async function() {}
对象的方式: let obj = { async foo() {} }
箭头函数: const foo = async () => {}

处理单个异步结果:

async function asyncFunc(){
    const result = await otherAsyncFunc();
    console.log(result)
}

顺序处理多个异步结果:

async function asyncFunc(){
        const result1 = await otherAsyncFunc1();
        console.log(result1);
        const result2 = await otherAsyncFunc2();
        console.log(result2);
}

并行处理多个异步结果:

async function asyncFunc(){
    const [result1,result2] = await.Promise.all({
        otherAsyncFunc1(),
        otherAsyncFunc2()
    })
    console.log(result1,result2);
}

处理错误:

Async function asyncFunc(){
    try{
       Await otherAsyncFunc(); 
    }catch(err){
        console.log(err)
    }
}

Object.entries( )和Object.values( )
Object.entries( )
1.目标对象是对象时,则每一个键值对都将会编译成一个具有两个元素的数组
2.目标对象是数组时,则会将数组的下标作为键值返回

Object.entries({ one:1,two:2})            //[[‘one’,1],[’two’,2]]

Object.entries([1,2])                    //[[‘0’,1],[‘1’,2]]

注意:键值对中,如果键的值是Symbol,编译时将会被忽略。例如:
Object.entries({ [Symbol()]: 1, two: 2 }) //[['two', 2]]

Object.entries()返回的数组的顺序与for-in循环保持一致,即如果对象的key值是数字,则返回值会对key值进行排序,返回的是排序后的结果。例如:
Object.entries({ 3: 'a', 4: 'b', 1: 'c' }) //[['1', 'c'], ['3', 'a'], ['4', 'b']]

使用Object.entries(),我们还可以进行对象属性的遍历。例如

let obj = { one: 1, two: 2 };
for (let [k,v] of Object.entries(obj)) {
  console.log(`${JSON.stringify(k)}: ${JSON.stringify(v)}`);
}

//输出结果如下:
'one': 1
'two': 2

Object.values()
它的工作原理跟Object.entries()很像,顾名思义,它只返回自己的键值对中属性的值。它返回的数组顺序,也跟Object.entries()保持一致。

Object.values({ one: 1, two: 2 }) //[1, 2]
Object.values({ 3: 'a', 4: 'b', 1: 'c' }) //['c', 'a', 'b']

字符串填充:padStart和padEnd
ES8提供了新的字符串方法-padStart和padEnd。padStart函数通过填充字符串的首部来保证字符串达到固定的长度,反之,padEnd是填充字符串的尾部来保证字符串的长度的。该方法提供了两个参数:字符串目标长度和填充字段,其中第二个参数可以不填,默认情况下使用空格填充。

'Vue'.padStart(10)           //'       Vue'
'React'.padStart(10)         //'     React'
'JavaScript'.padStart(10)    //'JavaScript'

可以看出,多个数据如果都采用同样长度的padStart,相当于将呈现内容右对齐。
上面示例中我们只定义了第一个参数,那么我们现在来看看第二个参数,我们可以指定字符串来代替空字符串。

'Vue'.padStart(10, '_*')           //'_*_*_*_Vue'
'React'.padStart(10, 'Hello')      //'HelloReact'
'JavaScript'.padStart(10, 'Hi')    //'JavaScript'
'JavaScript'.padStart(8, 'Hi')     //'JavaScript'

从上面结果来看,填充函数只有在字符长度小于目标长度时才有效,若字符长度已经等于或小于目标长度时,填充字符不会起作用,而且目标长度如果小于字符串本身长度时,字符串也不会做截断处理,只会原样输出。
padEnd函数作用同padStart,只不过它是从字符串尾部做填充。来看个小例子:

'Vue'.padEnd(10, '_*')           //'Vue_*_*_*_'
'React'.padEnd(10, 'Hello')      //'ReactHello'
'JavaScript'.padEnd(10, 'Hi')    //'JavaScript'
'JavaScript'.padEnd(8, 'Hi')     //'JavaScript'

Object.getOwnPropertyDescriptors()
顾名思义,该方法会返回目标对象中所有属性的属性描述符,该属性必须是对象自己定义的,不能是从原型链继承来的。先来看个它的基本用法:

let obj = {
  id: 1,
  name: 'test',
  get gender() {
    console.log('gender')
  },
  set grade(g) {
    console.log(g)
  }
}
Object.getOwnPropertyDescriptors(obj)

//输出结果为:

{
  gender: {
    configurable: true,
    enumerable: true,
    get: f gender(),
    set: undefined
  },
  grade: {
    configurable: true,
    enumerable: true,
    get: undefined,
    set: f grade(g)
  },
  id: {
    configurable: true,
    enumerable: true,
    value: 1,
    writable: true
  },
  name: {
    configurable: true,
    enumerable: true,
    value: 'test',
    writable: true
  }
}

方法还提供了第二个参数,用来获取指定属性的属性描述符。

let obj = {
  id: 1,
  name: 'test',
  get gender() {
    console.log('gender')
  },
  set grade(g) {
    console.log(g)
  }
}
Object.getOwnPropertyDescriptors(obj, 'id')

//输出结果为:

{
  id: {
    configurable: true,
    enumerable: true,
    value: 1,
    writable: true
  }
}

由上述例子可知,该方法返回的描述符,会有两种类型:数据描述符、存取器描述符。返回结果中包含的键可能的值有:configurable、enumerable、value、writable、get、set。
使用过Object.assign()的同学都知道,assign方法只能拷贝一个属性的值,而不会拷贝它背后的复制方法和取值方法。Object.getOwnPropertyDescriptors()主要是为了解决Object.assign()无法正确拷贝get属性和set属性的问题。

let obj = {
  id: 1,
  name: 'test',
  get gender() {
    console.log('gender')
  }
}
Object.assign(obj)

//输出结果为:

{
  gender: undefined
  id: 1,
  name: 'test'
}

此时,Object.getOwnPropertyDescriptors方法配合Object.defineProperties方法,就可以实现正确拷贝。

let obj = {
  id: 1,
  name: 'test',
  get gender() {
    console.log('gender')
  }
}
let obj1 = {}
Object.defineProperties(obj1, Object.getOwnPropertyDescriptors(obj))
Object.getOwnPropertyDescriptors(obj1)

//输出结果为:

{
  gender: {
    configurable: true,
    enumerable: true,
    get: f gender(),
    set: undefined
  },
  id: {
    configurable: true,
    enumerable: true,
    value: 1,
    writable: true
  },
  name: {
    configurable: true,
    enumerable: true,
    value: 'test',
    writable: true
  }
}

上述代码演示了,我们如何来拷贝一个属性值为赋值方法或者取值方法的对象。更多Object.getOwnPropertyDescriptors的使用细则,可参见阮一峰的博客文章,链接奉上:http://es6.ruanyifeng.com/#docs/object#Object-getOwnPropertyDescriptors
共享内存和原子(Shared memory and atomics)
ES8引入了两部分内容:新的构造函数SharedArrayBuffer、具有辅助函数的命名空间对象Atomics。共享内存允许多个线程并发读写数据,而原子操作则能够进行并发控制,确保多个存在竞争关系的线程顺序执行。
共享内存和原子也称为共享阵列缓冲区,它是更高级的并发抽象的基本构建块。它允许在多个工作者和主线程之间共享SharedArrayBuffer对象的字节(缓冲区是共享的,用以访问字节,将其包装在类型化的数组中)。这种共享有两个好处:
可以更快地在web worker之间共享数据
web worker之间的协调变得更加简单和快速
那么,我们为什么要引入共享内存和原子的概念呢?以及SharedArrayBuffer的竞争条件是什么,Atomics又是如何解决这种竞争的?推荐下面的文章,文章讲解很详细,图文并茂,带你深入了解SharedArrayBuffer和Atomics。
内存管理碰撞课程:https://segmentfault.com/a/1190000009878588
图解 ArrayBuffers 和 SharedArrayBuffers:https://segmentfault.com/a/1190000009878632
用 Atomics 避免 SharedArrayBuffers 竞争条件:https://segmentfault.com/a/1190000009878699
Atomics对象提供了许多静态方法,配合SharedArrayBuffer对象一起使用,可以帮助我们去构建一个内存共享的多线程编程环境。Atomic操作安装在Atomics模块上。与其他全局对象不同,Atomics不是构造函数。您不能使用new操作符或Atomics作为函数调用该对象。所有的属性和方法Atomics都是静态的,这一点跟Math类似。下面链接贴出了Atomics提供的一些基本方法:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics
关于共享内存和原子的深入研究,也可以参考Axel Rauschmayer博士的《Exploring ES2016 and ES2017》一书中的内容。具体章节链接如下:
http://exploringjs.com/es2016-es2017/ch_shared-array-buffer.html
函数参数列表与调用中的尾部逗号
该特性允许我们在定义或者调用函数时添加尾部逗号而不报错。

let foo = function (
  a,
  b,
  c,
) {
  console.log('a:', a)
  console.log('b:', b)
  console.log('c:', c)
}
foo(1, 3, 4, )

//输出结果为:
a: 1
b: 3
c: 4

上面这种方式调用是没有问题的。函数的这种尾逗号也是向数组和字面量对象中尾逗号看齐,它适用于那种多行参数并且参数名很长的情况,开发过程中,如果忘记删除尾部逗号也没关系,ES8已经支持这种写法。
这么用有什么好处呢?
首先,当我们调整结构时,不会因为最后一行代码的位置变动,而去添加或者删除逗号。
其次,在版本管理上,不会出现因为一个逗号,而使本来只有一行的修改,变成两行。例如下面:

(
'abc'
)

(
'abc',
'def'
)

在我们版本管理系统里,它会监测到你有两处更改,但是如果我们不必去关心逗号的存在,每一行都有逗号时,新加一行,也只会监测到一行的修改。
建议的ES9功能
回想一下,每个ECMAScript功能提案都经过了几个阶段:
阶段4意味着功能将在下一个版本中(或之后的版本)。
阶段3意味着功能仍然有机会被包含在下一个版本中。
第4阶段和部分ECMAScript规范草案
以下功能目前在第4阶段:
Template Literal Revision:模板文字修订(蒂姆·迪士尼)
候选功能(第3阶段)
以下功能目前在第3阶段:
Function.prototype.toString 修订版(Michael Ficarra)
global(Jordan Harband)
Rest/Spread Properties:Rest/Spread属性(SebastianMarkbåge)
Asynchronous Iteration:异步迭代(Domenic Denicola)
import() (Domenic Denicola)
RegExp Lookbehind Assertions:RegExp Lookbehind断言(Daniel Ehrenberg)
RegExp Unicode Property Escapes:RegExp Unicode属性转义(Brian Terlson,Daniel Ehrenberg,Mathias Bynens)
RegExp named capture groups:RegExp命名捕获组(Daniel Ehrenberg,Brian Terlson)
s (dotAll) flag for regular expressions:s(dotAll)标志为正则表达式(Mathias Bynens,Brian Terlson)
Promise.prototype.finally() (Jordan Harband)
BigInt - 任意精度整数(Daniel Ehrenberg)
Class fields(Daniel Ehrenberg,Jeff Morrison)
Optional catch binding(Michael Ficarra)
ES6-ES8的学习网站
ES6:http://es6.ruanyifeng.com/
ES7:https://www.css88.com/archives/tag/es7
ES8:https://www.css88.com/archives/tag/es8
TC39提案--javascript发展委员会

猜你喜欢

转载自www.cnblogs.com/broad/p/9987614.html
今日推荐