shinena / myProject

1 stars 0 forks source link

ES2017改进 #21

Open shinena opened 5 years ago

shinena commented 5 years ago

ECMAScript 2017,ECMA-262 标准的第八版(称作 ES2017 或者 ES8),2017年6月发布。 和 ES6 相比,ES8 仍然带来了很多有用的功能:

String padding Object.values Object.entries Object.getOwnPropertyDescriptors() 函数参数尾逗号 异步函数 Shared memory and atomics

String padding String padding 的目的是为一个字符串添加字符,让它可以和声明的长度一致。 ES2017 引入了两个 String 上的方法:padStart() 和 padEnd()。 padStart(targetLength [, padString]) padEnd(targetLength [, padString]) 复制代码例子: padStart() 输出

'test'.padStart(4) 'test'

'test'.padStart(5) ' test'

'test'.padStart(8) '    test'

'test'.padStart(8, 'abcd') 'abcdtest'

padEnd() 输出

'test'.padEnd(4) 'test'

'test'.padEnd(5) 'test '

'test'.padEnd(8) 'test    '

'test'.padEnd(8, 'abcd') 'testabcd'

Object.values() 这个方法返回一个包含对象自身属性值的数组。用法: const person = { name: 'Fred', age: 87 } Object.values(person) // ['Fred', 87] 复制代码Object.values() 也可以用于数组: const people = ['Fred', 'Tony'] Object.values(people) // ['Fred', 'Tony'] 复制代码Object.entries() 这个方法返回一个 [key, value] 形式的包含对象自身所有属性及值的数组。用法: const person = { name: 'Fred', age: 87 } Object.entries(person) // [['name', 'Fred'], ['age', 87]] 复制代码Object.entries() 也可以用于数组: const people = ['Fred', 'Tony'] Object.entries(people) // [['0', 'Fred'], ['1', 'Tony']] 复制代码getOwnPropertyDescriptors() 这个方法返回对象自身的所有描述符(非继承)。 JavaScript 中的所有对象都有一个属性集合,每个属性都有一个描述符。 描述符是属性的 attribute 集合,它包括下面这些子集:

value:属性的值 writable:为 true 时属性可以重写 get:属性的 getter 函数,当读取属性时被调用 set:属性的 setter 函数,当设置属性值时被调用 configurable:如果为 false,属性不能被删除,而且不能更改所有的 attribute 值,属性自身的值除外 enumerable:为 true 时属性可枚举

Object.getOwnPropertyDescriptors(obj) 接受对象作为参数,返回一个包含描述符的对象。 这有什么用? ES2015 给我们带来了 Object.assign(),方便我们复制一个或多个对象自身的可枚举属性,返回一个新对象。 然而这样操作有个问题,它无法正确复制没有默认 attributes 的属性。举个例子,如果一个对象只有一个 setter,就不能用 Object.assign() 正确复制它。 const person1 = { set name(newName) { console.log(newName) } } 复制代码这样不会工作: const person2 = {} Object.assign(person2, person1) 复制代码但是这样可以: const person3 = {} Object.defineProperties(person3, Object.getOwnPropertyDescriptors(person1)) 复制代码你可以通过控制台简单测试一下: person1.name = 'x' "x" person2.name = 'x'

person3.name = 'x' "x" 复制代码person2 没有 setter,它不能被正确复制。 使用 Object.create() 对对象浅克隆也有同样的限制。 尾后逗号 这个功能允许在函数声明和函数调用中使用尾后逗号: const doSomething = (var1, var2,) => { //... } doSomething('test2', 'test2',) 复制代码这个改变将鼓励开发者停止使用丑陋的“行首逗号”的习惯。 异步函数 ES2017 引入了异步函数的概念,它也是这个 ECMAScript 版本里最重要的变化。 异步函数结合了 promises 和 generators 以减少 promises 带来的样板风格和 promises 链的“不要打破调用链”限制。 为什么他们很有用 它是对 promises 函数的高级抽象。 当 ES2015 里引入 Promises 的时候,这个功能致力于解决异步代码的问题。但是在 ES2015 到 ES2017 发布的两年里,人们清楚的认识到这不是解决问题的最终方法。 引入 Promises 用来解决著名的回调地狱问题,但是也带来了自身的复杂性,加大了语法的复杂程度。他们是很好的开端,在这个基础上可以让开发者使用更好的语法:那就是异步函数。 一个简短的例子 使用异步函数的代码可以像这样: function doSomethingAsync() { return new Promise((resolve) => { setTimeout(() => resolve('I did something'), 3000) }) } async function doSomething() { console.log(await doSomethingAsync()) } console.log('Before') doSomething() console.log('After') 复制代码上面的代码会在浏览器控制台里打印出: Before After I did something //after 3s 复制代码串联多个异步函数 链式调用异步函数很简单,而且比原始的 promises 更易读: function promiseToDoSomething() { return new Promise((resolve)=>{ setTimeout(() => resolve('I did something'), 10000) }) } async function watchOverSomeoneDoingSomething() { const something = await promiseToDoSomething() return something + ' and I watched' } async function watchOverSomeoneWatchingSomeoneDoingSomething() { const something = await watchOverSomeoneDoingSomething() return something + ' and I watched as well' } watchOverSomeoneWatchingSomeoneDoingSomething().then((res) => { console.log(res) }) 复制代码共享内存和原子 WebWorkers 用来在浏览器里构建多线程程序。 他们通过事件(events)提供一种通信协议。从 ES2017 开始,你可以通过 SharedArrayBuffer 在 web workers 和他们的构造者中间创建一个共享内存数组。 由于我们不知道写入一个共享内存的传递部分需要多长事件,因此原子(Atomics)是一种在读取值时执行操作的方法,并且完成了所有类型的写入操作。 更多内容可以在这个提案中找到,该提案已经被实现。


作者:隐 链接:https://juejin.im/post/5bff57fee51d45021a167991