async/await

  1. # async/await
  2. 异步函数存在以下四种使用形式:
  3. 函数声明: async function foo() {}
  4. 函数表达式: const foo = async function() {}
  5. 对象的方式: let obj = { async foo() {} }
  6. 箭头函数: const foo = async () => {}
  7. 虽然Promise可以解决回调地狱的问题,但是链式调用太多,则会变成另一种形式的回调地狱 —— 面条地狱,所以在ES8里则出现了Promise的语法糖async/await,专门解决这个问题。
  8. 我们先看一下下面的Promise代码:
  9. fetch('coffee.jpg')
  10. .then(response => response.blob())
  11. .then(myBlob => {
  12. let objectURL = URL.createObjectURL(myBlob)
  13. let image = document.createElement('img')
  14. image.src = objectURL
  15. document.body.appendChild(image)
  16. })
  17. .catch(e => {
  18. console.log('There has been a problem with your fetch operation: ' + e.message)
  19. })
  20. 然后再看看async/await版的,这样看起来是不是更清晰了。
  21. async function myFetch() {
  22. let response = await fetch('coffee.jpg')
  23. let myBlob = await response.blob()
  24. let objectURL = URL.createObjectURL(myBlob)
  25. let image = document.createElement('img')
  26. image.src = objectURL
  27. document.body.appendChild(image)
  28. }
  29. myFetch()
  30. 当然,如果你喜欢,你甚至可以两者混用
  31. async function myFetch() {
  32. let response = await fetch('coffee.jpg')
  33. return await response.blob()
  34. }
  35. myFetch().then((blob) => {
  36. let objectURL = URL.createObjectURL(blob)
  37. let image = document.createElement('img')
  38. image.src = objectURL
  39. document.body.appendChild(image)
  40. })

Object.values()

  1. # Object.values()
  2. Object.values()方法返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for...in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。
  3. 代码如下:
  4. const object1 = {
  5. a: 'somestring',
  6. b: 42,
  7. c: false
  8. }
  9. console.log(Object.values(object1)) // ["somestring", 42, false]

Object.entries()

  1. # Object.entries()
  2. Object.entries()方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。
  3. 代码如下:
  4. const object1 = {
  5. a: 'somestring',
  6. b: 42
  7. }
  8. for (let [key, value] of Object.entries(object1)) {
  9. console.log(`${key}: ${value}`)
  10. }
  11. // "a: somestring"
  12. // "b: 42"

padStart()

  1. # padStart()
  2. padStart() 方法用另一个字符串填充当前字符串(重复,如果需要的话),以便产生的字符串达到给定的长度。填充从当前字符串的开始(左侧)应用的。
  3. 代码如下:
  4. const str1 = '5'
  5. console.log(str1.padStart(2, '0')) // "05"
  6. const fullNumber = '2034399002125581'
  7. const last4Digits = fullNumber.slice(-4)
  8. const maskedNumber = last4Digits.padStart(fullNumber.length, '*')
  9. console.log(maskedNumber) // "************5581"

padEnd()

  1. # padEnd()
  2. padEnd() 方法会用一个字符串填充当前字符串(如果需要的话则重复填充),返回填充后达到指定长度的字符串。从当前字符串的末尾(右侧)开始填充。
  3. const str1 = 'Breaded Mushrooms'
  4. console.log(str1.padEnd(25, '.')) // "Breaded Mushrooms........"
  5. const str2 = '200'
  6. console.log(str2.padEnd(5)) // "200 "

函数参数结尾逗号(Function parameter lists and calls trailing commas)

  1. # 函数参数结尾逗号(Function parameter lists and calls trailing commas
  2. ES5里就添加了对象的尾逗号,不过并不支持函数参数,但是在ES8之后,便开始支持这一特性,代码如下:
  3. // 参数定义
  4. function f(p) {}
  5. function f(p,) {}
  6. (p) => {}
  7. (p,) => {}
  8. class C {
  9. one(a,) {},
  10. two(a, b,) {},
  11. }
  12. var obj = {
  13. one(a,) {},
  14. two(a, b,) {},
  15. };
  16. // 函数调用
  17. f(p)
  18. f(p,)
  19. Math.max(10, 20)
  20. Math.max(10, 20,)
  21. 但是以下的方式是不合法的:
  22. 仅仅包含逗号的函数参数定义或者函数调用会抛出 SyntaxError。而且,当使用剩余参数的时候,并不支持尾后逗号,例子如下:
  23. function f(,) {} // SyntaxError: missing formal parameter
  24. (,) => {} // SyntaxError: expected expression, got ','
  25. f(,) // SyntaxError: expected expression, got ','
  26. function f(...p,) {} // SyntaxError: parameter after rest parameter
  27. (...p,) => {} // SyntaxError: expected closing parenthesis, got ','
  28. 在解构里也可以使用,代码如下:
  29. // 带有尾后逗号的数组解构
  30. [a, b,] = [1, 2]
  31. // 带有尾后逗号的对象解构
  32. var o = {
  33. p: 42,
  34. q: true,
  35. }
  36. var {p, q,} = o
  37. 同样地,在使用剩余参数时,会抛出 SyntaxError,代码如下:
  38. var [a, ...b,] = [1, 2, 3] // SyntaxError: rest element may not have a trailing comma

ShareArrayBuffer(因安全问题,暂时在Chrome跟FireFox中被禁用)

  1. # ShareArrayBuffer(因安全问题,暂时在ChromeFireFox中被禁用)
  2. SharedArrayBuffer 对象用来表示一个通用的,固定长度的原始二进制数据缓冲区,类似于 ArrayBuffer 对象,它们都可以用来在共享内存(shared memory)上创建视图。与 ArrayBuffer 不同的是,SharedArrayBuffer 不能被分离。
  3. 代码如下:
  4. et sab = new SharedArrayBuffer(1024) // 必须实例化
  5. worker.postMessage(sab)

Atomics对象

  1. # Atomics对象
  2. Atomics对象 提供了一组静态方法用来对 SharedArrayBuffer[3] 对象进行原子操作。
  3. 方法如下:
  4. Atomics.add() :将指定位置上的数组元素与给定的值相加,并返回相加前该元素的值。
  5. Atomics.and():将指定位置上的数组元素与给定的值相与,并返回与操作前该元素的值。
  6. Atomics.compareExchange():如果数组中指定的元素与给定的值相等,则将其更新为新的值,并返回该元素原先的值。
  7. Atomics.exchange():将数组中指定的元素更新为给定的值,并返回该元素更新前的值。
  8. Atomics.load():返回数组中指定元素的值。
  9. Atomics.or():将指定位置上的数组元素与给定的值相或,并返回或操作前该元素的值。
  10. Atomics.store():将数组中指定的元素设置为给定的值,并返回该值。
  11. Atomics.sub():将指定位置上的数组元素与给定的值相减,并返回相减前该元素的值。
  12. Atomics.xor():将指定位置上的数组元素与给定的值相异或,并返回异或操作前该元素的值。
  13. Atomics.wait():检测数组中某个指定位置上的值是否仍然是给定值,是则保持挂起直到被唤醒或超时。返回值为 "ok""not-equal" "time-out"。调用时,如果当前线程不允许阻塞,则会抛出异常(大多数浏览器都不允许在主线程中调用 wait())。
  14. Atomics.wake():唤醒等待队列中正在数组指定位置的元素上等待的线程。返回值为成功唤醒的线程数量。
  15. Atomics.isLockFree(size):可以用来检测当前系统是否支持硬件级的原子操作。对于指定大小的数组,如果当前系统支持硬件级的原子操作,则返回 true;否则就意味着对于该数组,Atomics 对象中的各原子操作都只能用锁来实现。此函数面向的是技术专家。

Object.getOwnPropertyDescriptors()

  1. # Object.getOwnPropertyDescriptors()
  2. Object.getOwnPropertyDescriptors() 方法用来获取一个对象的所有自身属性的描述符。代码如下:
  3. const object1 = {
  4. property1: 42
  5. }
  6. const descriptors1 = Object.getOwnPropertyDescriptors(object1)
  7. console.log(descriptors1.property1.writable) // true
  8. console.log(descriptors1.property1.value) // 42
  9. // 浅拷贝一个对象
  10. Object.create(
  11. Object.getPrototypeOf(obj),
  12. Object.getOwnPropertyDescriptors(obj)
  13. )
  14. // 创建子类
  15. function superclass() {}
  16. superclass.prototype = {
  17. // 在这里定义方法和属性
  18. }
  19. function subclass() {}
  20. subclass.prototype = Object.create(superclass.prototype, Object.getOwnPropertyDescriptors({
  21. // 在这里定义方法和属性
  22. }))

修饰器