ES2017 中对 Javascript 的新增和改进

1、 字符串填充 String padding

String 增加了两个实例方法 — padStartpadEnd,这两个方法可以在字符串的首/尾添加其他字符串,类似数组的 unshift,push 方法
语法
str.padStart(targetLength [, padString])
str.padEnd(targetLength [, padString])
参数
targetLength
当前字符串需要填充到的目标长度。如果这个数值小于当前字符串的长度,则返回当前字符串本身。
padString 可选
填充字符串。如果字符串太长,使填充后的字符串长度超过了目标长度,则只保留最左侧/右侧的部分,其他部分会被截断。此参数的默认值为 " "(U+0020)。
例子
"es8".padStart(2); // 'es8'
"es8".padStart(5); // '  es8'
"es8".padStart(6, "woof"); // 'wooes8'
"es8".padStart(14, "wow"); // 'wowwowwowwoes8'
"es8".padStart(7, "0"); // '0000es8'
"es8".padEnd(2); // 'es8'
"es8".padEnd(5); // 'es8  '
"es8".padEnd(6, "woof"); // 'es8woo'
"es8".padEnd(14, "wow"); // 'es8wowwowwowwo'
"es8".padEnd(7, "6"); // 'es86666'

2、 对象值遍历 Object.values

Object.values 函数会返回指定对象的可枚举的属性值数组,数组中值顺序与 for-in 循环保持一致,函数的声明为:
Object.values(obj);
首个参数 obj 即为需要遍历的目标对象,它可以为某个对象或者数组(数组可以看做键为下标的对象):
const obj = { x: "xxx", y: 1 };
Object.values(obj); // ['xxx', 1]

const obj = ["e", "s", "8"]; // same as { 0: 'e', 1: 's', 2: '8' };
Object.values(obj); // ['e', 's', '8']

// 当使用数字作为key时,返回的值的顺序是和key的大小顺序一致的
const obj = { 10: "xxx", 1: "yyy", 3: "zzz" };
Object.values(obj); // ['yyy', 'zzz', 'xxx']
Object.values("es8"); // ['e', 's', '8']

2、 对象键和值的遍历 Object.entries

Object.keys 和 Object.values 的结合体,方法返回一个给定对象自身可枚举属性的键值对数组,数组中顺序与 Object.values 保持一致,数组的每一项为[key, value]
const obj = { x: "xxx", y: 1 };
Object.entries(obj); // [['x', 'xxx'], ['y', 1]]

const obj = ["e", "s", "8"];
Object.entries(obj); // [['0', 'e'], ['1', 's'], ['2', '8']]

const obj = { 10: "xxx", 1: "yyy", 3: "zzz" };
Object.entries(obj); // [['1', 'yyy'], ['3', 'zzz'], ['10': 'xxx']]
Object.entries("es8"); // [['0', 'e'], ['1', 's'], ['2', '8']]

3、 获取对象的属性描述符 Object.getOwnPropertyDescriptors, Object.getOwnPropertyDescriptor

getOwnPropertyDescriptors 函数会返回指定对象的某个指定属性的描述符;该属性必须是对象自己定义而不是继承自原型链,函数的声明为:
Object.getOwnPropertyDescriptor(obj, prop);
Object.getOwnPropertyDescriptors(obj);
obj 即为源对象,而 prop 即为需要查看的属性名;结果中包含的键可能有 configurable、enumerable、writable、get、set 以及 value。
const obj = {
  get es8() {
    return 888;
  },
};
Object.getOwnPropertyDescriptor(obj, "es8");
// {
//   configurable: true,
//   enumerable: true,
//   get: function es8(){}, //the getter function
//   set: undefined
// }

const objj = {
  a: 1,
  b: "2",
  c: true,
  d: null,
  e: undefined,
  f: {},
};
Object.getOwnPropertyDescriptors(objj);
// {
//   a: {value: 1, writable: true, enumerable: true, configurable: true},
//   b: {value: "2", writable: true, enumerable: true, configurable: true},
//   c: {value: true, writable: true, enumerable: true, configurable: true},
//   d: {value: null, writable: true, enumerable: true, configurable: true},
//   e: {value: undefined, writable: true, enumerable: true, configurable: true},
//   f: {value: {}, writable: true, enumerable: true, configurable: true},
// }

4、 函数参数列表与调用中的尾部逗号 Trailing commas in function

JavaScript 一开始就支持数组字面值中的尾后逗号,随后向对象字面值(ECMAScript 5)中添加了尾后逗号。
ES8 标准中允许函数参数列表与调用中的尾部逗号,该特性允许我们在定义或者调用函数时添加尾部逗号。
但是 JSON 不支持尾后逗号
function es8(var1, var2, var3) {
  // do something
  //函数内部的 arguments.length 是 3 还是 4 ?
  console.log(arguments.length); // 3
}
es8(10, 20, 30);

5、 异步函数 Async function

async 函数是使用 async 关键字声明的函数。 async 函数是 AsyncFunction 构造函数的实例, 并且其中允许使用 await 关键字。async 和 await 关键字让我们可以用一种更简洁的方式写出基于 Promise 的异步行为,而无需刻意地链式调用 promise。
ES8 中允许使用 async/await 语法来定义与执行异步函数,async 关键字会返回某个 AsyncFunction 对象;在内部实现中虽然异步函数与迭代器的实现原理类似,但是其并不会被转化为迭代器函数:
function resolveAfter2Seconds() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve("resolved");
    }, 2000);
  });
}

async function asyncCall() {
  console.log("calling");
  const result = await resolveAfter2Seconds();
  console.log(result);
}

asyncCall();
// calling
// resolved

6、 共享内存与原子操作 SharedArrayBuffer, Atomics

SharedArrayBuffer
SharedArrayBuffer 对象用来表示一个通用的,固定长度的原始二进制数据缓冲区,类似于 ArrayBuffer 对象,它们都可以用来在共享内存(shared memory)上创建视图。与 ArrayBuffer 不同的是,SharedArrayBuffer 不能被分离。
共享内存能被同时创建和更新于工作者线程或主线程。依赖于系统(CPU,操作系统,浏览器),变化传递给环境需要一段时间。需要通过 atomic 操作来进行同步。
Atomics
Atomics 对象提供了一组静态方法用来对 SharedArrayBuffer 对象进行原子操作。
这些原子操作属于 Atomics 模块。与一般的全局对象不同,Atomics 不是构造函数,因此不能使用 new 操作符调用,也不能将其当作函数直接调用。Atomics 的所有属性和方法都是静态的(与 Math 对象一样)。
多个共享内存的线程能够同时读写同一位置上的数据。原子操作会确保正在读或写的数据的值是符合预期的,即下一个原子操作一定会在上一个原子操作结束后才会开始,其操作过程不会中断。
posted @ 2021-05-11 23:29  Frank-Link  阅读(8)  评论(0编辑  收藏  举报