ES6~ES13 36大新特性大盘点?

大家好,很高兴又见面了,我是"前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!

前端进阶

1.ES6 (ES2015)

1.1 Class

JavaScript 是一种使用原型链的语言。 早期像面向对象这样的概念都是通过原型链来做的,比较复杂,Class 终于在 ES6 中引入了。

class Animal {
  constructor(name, color) {
    this.name = name;
    this.color = color;
  }
  // This is a property on the prototype chain
  toString() {
    console.log('name:' + this.name + ', color:' + this.color);
  }
}
var animal = new Animal('myDog', 'yellow');
animal.toString();
console.log(animal.hasOwnProperty('name')); //true
console.log(animal.hasOwnProperty('toString')); // false
console.log(animal.__proto__.hasOwnProperty('toString')); // true
class Cat extends Animal {
  constructor(action) {
    super('cat', 'white');
    this.action = action;
  }
  toString() {
    console.log(super.toString());
  }
}

var cat = new Cat('catch');
cat.toString();
console.log(cat instanceof Cat); // true
console.log(cat instanceof Animal); // true

1.2 module

每个模块都有自己的命名空间,避免冲突,使用 import 和 export 来导入导出,默认将 .js 文件视为模块。

1.3 Arrow function 箭头函数

() => {…}是函数的缩写,有了箭头函数再‬也不用写 var self = this, var that = this 等类代码。

const add = (a, b) => {
  return a + b;
};
const res = add(1, 2); // 3
const minus = (a, b) => a - b;
const res1 = minus(5, 1); // 4

1.4 函数参数默认值

如果函数不传参数,则使用默认值,更简洁。

function example(height = 5, width = 6) {
  const newH = height * 2;
  const newW = width * 4;
  return newH + newW;
}
example(); // 34 (5*2 + 6*4)

1.5 模板字符串

以前,长字符串的组合使用+号连接,可读性差,使用模板字符串更容易阅读。

const firstName = 'water';
const lastName = 'fish';
// not use template literal
const name = 'Hello, My name is' + firstName + ', ' + lastName;
// use template literal
const nameWithLiteralString = `Hello, My name is ${firstName}, ${lastName}`;

1.6 解构

const arr = [1, 2, 3, 4, 5];
const [one, two, three] = arr;
console.log(one); // 1
console.log(two); // 2
...
// To skip certain values
const [first,,,,last] = arr;
console.log(first); // 1
console.log(last); // 5

// Objects can also be destructurized and assigned
const student = {
    name: 'waterfish',
    age: 28,
};
const {name, age, city} = student;
console.log(name); // "waterfish"
console.log(age); // "28"

1.7 spread 操作符

const arr1 = ['A', 'B'];
const arr2 = ['0', ...arr1, '1', '2'];
conslog.log(arr2); // ["0", "A", "B", "1", "2"]

用三个点…表示,Array 可以扩展,而如果是 Object,则根据 key-value 进行扩展。

1.8 对象属性缩写

因为构成 newCustomer 对象属性的 name、age 的 key、value 相同,所以省略 value。

const name = 'waterfish',
  age = 28;
// Before ES6, we must write like this
const customer = {
  name: name,
  age: age,
}; // // {name: 'waterfish', age: 28}

// After ES6, we can do it
const newCustomer = {
  name,
  age,
}; // // {name: 'waterfish', age: 28}

1.9 Promise

Promise 是一种解决异步(非同步)写法的方案,比原来的 callback 写法更优雅。使用 Promise 可以解决 hell callback。

const waitSecond = new Promise((resolve, reject) => {
  setTimeout(resolve, 1000);
});
waitSecond
  .then(() => {
    console.log('hello after 1 second.');
    // output this line after 1 second
    return waitSecond;
  })
  .then(() => {
    console.log('World after 2 sceond.');
    // output this line after 2second
  });

ES8(ES2017)发布了一个更完美的 async,await,直接让异步的写法看起来像同步的。

1.10 let, const 替换 var

2.ES7 (ES2016)

2.1 Array.prototype.includes()

用于判断数组中是否包含指定值,如果包含则返回 true,否则,返回 false。因为返回布尔值,比 indexOf 的语义化更加清晰。

const arr = [1, 2, 3, 4, 5];
arr.include(3); // true

if (arr.include(3)) { ... }
// ... Equivalent to the previous writing of indexOf
arr.indexOf(3); // 2 (return its array position)
// If you want to write it in the if, you must add `> -1`, which is not as clear as the include in ES7 in terms of semantics
if (arr.indexOf(3) > -1) { ... }

2.2 指数运算符

console.log(2 ** 10); // 1024
// equal to
console.log(Math.pow(2, 10)); // 1024

3.ES8 (ES2017)

3.1 async, await

异步函数是使用 async 关键字声明的函数,其中允许使用 await 关键字。 async 和 await 关键字使基于 Promise 的异步行为能够以更简洁的方式编写,避免显式配置 Promise 链的需要。

async test() {
    try {
        const result = await otherAsyncFunction();
        console.log(result); // output result
    } catch(e) {
        console.log(e); // Can catch errors if otherAsyncFunction() throws an error
    }
}

3.2 Object.values()

返回对象自身属性的所有值,不包括继承的值。

const exampleObj = { a: 1, b: 2, c: 3, d: 4 };
console.log(Object.value(exampleObj)); // [1, 2, 3, 4];
// To do the same thing before, use the following notation. much verbose
const values = Object.keys(exampleObj).map((key) => exampleObj[key]);

3.3 Object.entries()

返回一个可枚举的键,value 中存储的是键的值。

const Obj = { a: 1, b: 2, c: 3, d: 4 };
console.log(Object.entries(Obj)); // [["a", 1], ["b", 2], ["c", 3], ["d", 4]];

// Usually used with for
for (const [key, value] of Object.entries(Obj)) {
  console.log(`key: ${key}, value: ${value}`);
}
// key: a, value: 1
// key: b, value: 2
// key: c, value: 3
// key: d, value: 4

3.4 padStart() & padEnd()

您可以在字符串的开头或结尾添加额外的内容,并将其填充到指定的长度。过去,这些功能通常是通过 lodash 等通用帮助工具包引入 的。

String.padStart(fillingLength, FillingContent);
// If the content to be filled is too much and exceeds the "fill length",
// it will be filled from the leftmost to the upper limit of the length,
// and the excess will be truncated

最常用的情况应该是金额,填指定长度,不足补 0。

// padStart
'100'.padStart(5, 0); // 00100
// If the content to be padded exceeds the "padding length". Then fill in from the left to the upper limit of the length
'100'.padStart(5, '987'); // 98100

// padEnd
'100'.padEnd(5, 9); // 10099
// If the content to be padded exceeds the "padding length". Then fill in from the right to the upper limit of the length
'100'.padEnd(5, '987'); // 10098

3.5 trailing comma

ECMAScript 2017 支持函数参数中的尾随逗号。

function f(p) {}
function f(p) {}

(p) => {};
(p) => {};

3.6 Object.getOwnPropertyDescriptors()

获取您自己的描述符,一般开发业务需求通常不会使用这些描述符。

const exampleObj = { a: 1, b: 2, c: 3, d: 4 };
Object.getOwnPropertyDescriptors(exampleObj);
// {a: {…}, b: {…}, c: {…}, d: {…}}
// a: {value: 1, writable: true, enumerable: true, configurable: true}
// b: {value: 2, writable: true, enumerable: true, configurable: true}
// c: {value: 3, writable: true, enumerable: true, configurable: true}
// d: {value: 4, writable: true, enumerable: true, configurable: true}
// __proto__: Object

3.7 共享数组缓冲区(shared array buffer)

SharedArrayBuffer 是原始二进制数据的固定长度缓冲区,类似于 ArrayBuffer。可用于在共享内存上创建数据,与 ArrayBuffer 不同,SharedArrayBuffer 不能分离。

3.8 Atomics object

Atomics 对象提供一组静态方法来对 SharedArrayBuffer 执行原子操作。如果一个多线程同时在同一个位置读写数据,原子操作保证了正在操作的数据符合预期:即在上一个子操作结束后执行下一个,操作不中断。

可以说是针对 Node.Js 中多线程 Server 的开发而加强的功能,在前端开发中使用的机会相当低,目前 Chrome 已经支持。

3.ES9 (ES2018)

3.1 await loop

在异步函数中,有时需要在同步 for 循环中使用异步(非同步)函数。for 循环本身还是同步的,整个 for 循环会在循环中的异步函数执行完之前执行完,然后里面的异步函数会一个一个执行。ES9 加入了异步迭代器,允许 await 配合使用 for 循环逐步执行异步操作。

async function process(array) {
  for await (const i of array) {
    doSomething(i);
  }
}

3.2 promise.finally()

无论是成功(.then())还是失败(.catch()),都会在 Promise 之后执行的代码。

function process() {
  process1()
    .then(process2)
    .then(process3)
    .catch((err) => {
      console.log(err);
    })
    .finally(() => {
      console.log(`it must execut no matter success or fail`);
    });
}

3.3 Rest & Spread

const myObject = {
  a: 1,
  b: 2,
  c: 3,
};
const { a, ...r } = myObject;
// a = 1
// r = { b: 2, c: 3 }
// Can also be used in function input parameters
function restObjectInParam({ a, ...r }) {
  console.log(a); // 1
  console.log(r); // {b: 2, c: 3}
}
restObjectInParam({
  a: 1,
  b: 2,
  c: 3,
});

4.ES10 (ES2019)

4.1 Array.prototype.flat() & Array.prototype.flatMap()

const arr1 = [1, 2, [3, 4]];
arr1.flat(); // [1, 2, 3, 4]

const arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat(); // [1, 2, 3, 4, [5, 6]]
// Pass in a number in flat, representing the flattening depth
arr2.flat(2); // [1, 2, 3, 4, 5, 6]

下面是 flatMap 方法:

let arr = ['water', '', 'fish'];

arr.map((s) => s.split(''));
// [["w", "a", "t", "e", "r"], [""], ["f", "i", "s", "h"]

arr.flatMap((s) => s.split(''));
// ["w", "a","t","e","r", "", "f", "i", "s", "h"]

4.2 String.prototype.trimStart() & String.prototype.trimEnd()

trimStart() 方法从字符串的开头删除空格,trimLeft() 是该方法的别名。

const greeting = ' Hello world! ';
console.log(greeting);
// expected output: " Hello world! ";
console.log(greeting.trimStart());
// expected output: "Hello world! ";

trimEnd() 方法删除字符串末尾的空格,trimRight() 是该方法的别名。

const greeting = '   Hello world!   ';
console.log(greeting);
// expected output: "   Hello world!   ";
console.log(greeting.trimEnd());
// expected output: "   Hello world!";

4.3 Object.fromEntries()

将键值对列表转换为对象。

const entries = new Map([
  ['foo', 'bar'],
  ['baz', 42],
]);
const obj = Object.fromEntries(entries);
console.log(obj);
// expected output: Object { foo: "bar", baz: 42 }

4.4 String.prototype.matchAll

matchAll() 方法返回一个迭代器,遍历将字符串与正则表达式匹配的所有结果,包括捕获组。

const regexp = /t(e)(st(d?))/g;
const str = 'test1test2';
const array = [...str.matchAll(regexp)];
console.log(array[0]);
// expected output: Array ["test1", "e", "st1", "1"]
console.log(array[1]);
// expected output: Array ["test2", "e", "st2", "2"]

4.4 BigInt

const theBiggestInt = 9007199254740991n;
const alsoHuge = BigInt(9007199254740991);
// ↪ 9007199254740991n
const hugeString = BigInt('9007199254740991');
// ↪ 9007199254740991n
const hugeHex = BigInt('0x1fffffffffffff');
// ↪ 9007199254740991n
const hugeBin = BigInt(
  '0b11111111111111111111111111111111111111111111111111111'
);
// ↪ 9007199254740991n

5.ES11 (ES2020)

5.1 Promise.allSettled()

Promise.allSettled() 方法返回一个 Promise,当所有给定的 Promise 都已完成或被拒绝时,该 Promise 就会完成,其中每个对象都描述每个 Promise 的结果。

当您有多个不依赖于彼此成功完成的异步任务时,或者当您总是想知道每个 Promise 的结果时通常会使用它。

相反,如果任务相互依赖、或者您希望其中任何一个 Promise 失败后则立即拒绝,则由 Promise.all() 返回的 Promise 可能更合适。

const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) =>
  setTimeout(reject, 100, 'foo')
);
const promises = [promise1, promise2];
Promise.allSettled(promises).then((results) =>
  results.forEach((result) => console.log(result.status))
);
// expected output:
// "fulfilled"
// "rejected"

5.2 Optional ?

const username = user?.name || 'guest';

5.3 Nullish coalescing operator ??

在 JavaScript 中,0、null 或 undefined 会自动转为 false,但有时候希望将返回值设置为 0。

const username = user.level ?? 'no level';
// output 0. if level is not available, it becomes 'no level'.

5.4 Dynamic-import 动态引入

el.onclick = () => {
  import(`/js/logger.js`)
    .then((module) => {
      module.doSomthing();
    })
    .catch((err) => {
      handleError(err);
    });
};

5.5 GlobalThis

全局 globalThis 属性包含全局 this 值,类似于全局对象。

function canMakeHTTPRequest() {
  return typeof globalThis.XMLHttpRequest === 'function';
}
console.log(canMakeHTTPRequest());
// expected output (in a browser): true

6.ES12 (ES2021)

6.1 Promise.any()

Promise.any() 接受一个可迭代的 Promise 对象,每当可迭代对象中的任何一个 Promise fullfill 时它都返回一个 Promise,其中包含已 fullfill 的 Promise 的值。如果所有的 Promise reject 则返回 AggregateError 对象,其是 ERROR 对象的一个子类,默认搜集所有 Error 并分组。

const p1 = new Promise((resolve) => {
  setTimeout(() => {
    resolve('p1 resolved value');
  }, 1000);
});
const p2 = new Promise((resolve) => {
  setTimeout(() => {
    resolve('p2 resolved value');
  }, 500);
});
const p3 = new Promise((resolve) => {
  setTimeout(() => {
    resolve('p3 resolved value');
  }, 1800);
});
Promise.any([p1, p2, p3]).then((value) => {
  console.log(value);
}); // p2 resolved value

6.2 逻辑赋值运算符

在开发过程中,可以使用在 ES2020 引入的逻辑运算符 ||、&& 和 ?? (Nullish coalescing operator)来解决一些问题。而 ES2021 会提出 ||= , &&= , ??= ,概念类似于 += :

let b = 2;
b += 1;
// equal to b = b + 1
let a = null;
a ||= 'some random text'; // a become to'some random text'
// equal a = a || 'some random text'
let c = 'some random texts';
c &&= null; // c become to null
// equal to c = c && null
let d = null;
d ??= false; // d become to false
// equal to d = d ?? false

6.3 弱引用(WeakRef)

WeakRef 对象持有对对象的弱引用,称为其目标或引用对象。对对象的弱引用是不会阻止对象被垃圾收集器回收的引用。

普通(或强)引用将对象保存在内存中,当一个对象不再具有任何强引用时,JavaScript 引擎的垃圾收集器可能会销毁该对象并回收其内存,如果发生这种情况,您将无法再从弱引用中获取对象。

7.ES13 (ES2022)

期待不一样的东西

参考资料

原文链接:https://medium.com/@
waterfish/from-es6-to-es13-f72d4840986a

文字封面图片:https://app.daily.dev/posts/5k4Dlnc3E

展开阅读全文

页面更新:2024-03-13

标签:大新   进阶   写法   字符串   全局   函数   长度   属性   特性   对象   操作   方法

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top