2022-09-21【技术】总结es6 ~ es13所有新特性-下

书接上回

五、ES10(es2019)

(1)Array.prototype.flat()
es10为数组扁平化提供了两个api,通过参数控制扁平深度(默认深度为 1),话不多说直接上代码

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]]
const arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2); // [1, 2, 3, 4, 5, 6]
const arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

语法点评:有了它,就不用再自己封装扁平化方法了。

(2)Array.prototype.flatMap()

const arr = [1, 2, 3, 4];
arr.flatMap(x => [x * 2]); // [2, 4, 6, 8]
// 只有一层是扁平的
arr.flatMap(x => [[x * 2]]); // [[2], [4], [6], [8]]

语法点评:扁平化的扩展功能。

(3)Object.fromEntries()
它接收一个键值对列表(Map实例),并返回一个真实对象,其属性由条目给出。
它的功能与 Object.entries() 正相反。

const entries = new Map([
  ["apple", "origin"],
  ["grapes", "peach"]
]);
console.log(Object.fromEntries(entries)); 
// { apple: "origin", grapes: "peach" }

使用场景1:交换属性和值

function foo(obj) {
  return Object.fromEntries(Object.entries(obj)
    .map(([key, value]) => [value, key])
  )
}
console.table({ name: "oli", age: "12" })
console.table(foo({ name: "oli", age: "12" }))

使用场景2:将 url上的参数提取为一个对象

const params = Object.fromEntries(new URLSearchParams("foo=bar&baz=qux"));
console.log(params); // {foo: "bar", baz: "qux"}

语法点评:被低估的一个api,其实可以帮我们简化处理一些场景。

(4)String.prototype.trimStart() 和 String.prototype.trimEnd()
修整字符串前后的空格

let message = "     Hello      ";
message = message.trimEnd().trimStart();
console.log(message); // "Hello"

语法点评:搜索时,可以检测用户是不是只搜索了空格。

(5)try catch升级
catch的参数有时候是多余的,现在可以省略

try {
  const data = JSON.parse(obj)
  return true
} catch {
  return false
}

语法点评:很好,又为我们码农减了一点点负。

六、ES11(es2020)

(1)动态 import
通过import声明引用的所有模块(包括初始化暂时用不到的模块)都会在初始化阶段前置加载,影响首屏性能。

import()能够在函数、分支等非顶层作用域使用,按需加载、懒加载都不是问题。

例子:路由懒加载

import { lazy } from "react";
const route = [
  {
    title: "博客",
    path: "/home",
    component: lazy(() => import("@/views/Home")),
  },
  {
    title: "文章",
    path: "/article",
    search:"?category=all",
    component: lazy(() => import("@/views/Article")),
  },
  {
    path: "/article/:id",
    component: lazy(() => import("@/views/Article/ArticleDetail")),
  }
]

语法点评:性能优化新的突破。

(2)可选链-更详细的了解,请点击[https://blog.csdn.net/Ght19970126/article/details/122084892]
平时我们访问对象第n级的时候,可能某一级的节点并不存在,导致js程序崩溃。除非提前用if或者&&预判。
可选链操作符(?.) 通过用户检测不确定的中间节点,如果不存在中间节点则返回undefined。

//一个对象
const user = {
  info:{
    age: 11
  }
}

//要取值:
console.log(user.info.age) // 11

//当无法判断user对象中是否有info的属性,info属性下面是否有age属性我们会:
console.log(user&&user.info&&user.info.age)
//而有了?. 可选链运算符之后 可以如此
console.log(user?.info?.age)

语法点评:减负神技。

(3)Promise.allSettled
常规的promise.all并发多个实例只要有一个失败,就会停止执行并跳入catch方法。

而这个Promise.allSettled不管多个实例成功还是失败,一定会执行完,并将结果收集到一个数组中。

Promise.all([
    new Promise.reject("a1"),
    new Promise.resolve("a2")
]).then((ret) => {
    // 不会执行
    console.log(ret)
}).catch((error) => {
    // 因为有一个promise返回为reject。所以程序只会走到这里
    // 输出:a1
    console.log(error) 
})

// 使用es11的Promise.allSettled
Promise.allSettled([
    new Promise.reject("a1"),
    new Promise.resolve("a2")
]).then((ret) => {
    // 输出 
    // 0: {status: "fulfilled", value: "a1"},
    // 1: {status: "rejected", value: "a2"}
    console.log(ret)
    
    // 这样可以过滤掉rejected,避免整段程序运行错乱
    handleFun(ret.filter(el => el.status !== "rejected"))
})

语法点评:在需要执行多个的异步操作并收集所有结果时非常有效,即使某些异步操作可能失败。

(4)BigInt(第7个基本类型)
BigInt是一种特殊的数字类型,它支持任意长度的整数。

先说说它诞生的意义:
JS 中的Number类型只能安全地表示-9007199254740991 (-(2^53-1)) 和9007199254740991(2^53-1)之间的整数,任何超出此范围的整数值都可能失去精度。

// 注意最后一位的数字
29007199254740992 === 9007199254740993; //true

要创建一个 bigint,可以在一个整数的末尾添加字符n,或者调用函数 BigInt()。BigInt 函数使用字符串、数字等来创建一个BigInt。

19007199254740992n === 9007199254740993n; //false

语法点评:如果你需要用到这么大的数字,那它就派上用场了。

(5)全局this
全局this。在浏览器中它是 window, 在 Node.js 中它是global。


2jzduyuuzn.png

语法点评:好像除了在全局作用域快速拿到window,就没啥用了。

(6)String.protype.matchAll()
原有的 match() 方法仅返回完整的匹配结果,却不会返回特定正则表达式组。而 matchAll()返回的迭代器不仅包括精确的匹配结果,还有全部的正则模式捕获结果

var str = "From 2019.01.29 to 2019.01.30";
var allMatchs = str.matchAll(/(?<year>d{4}).(?<month>d{2}).(?<day>d{2})/g);
for (const match of allMatchs) {
  console.log(match);
}
// [
//   [
//     "2019.01.29",
//     "2019",
//     "01",
//     "29",
//     index: 5,
//     input: "From 2019.01.29 to 2019.01.30",
//     groups: [Object: null prototype] { year: "2019", month: "01", day: "29" }
//   ],
//   [
//     "2019.01.30",
//     "2019",
//     "01",
//     "30",
//     index: 19,
//     input: "From 2019.01.29 to 2019.01.30",
//     groups: [Object: null prototype] { year: "2019", month: "01", day: "30" }
//   ]
// ]

语法点评:正则家族又强大了,某些场景可能会很有用。

七、ES12(es2021)

(1)replaceAll
字符串新的原型方法(String.prototype.replaceAll)
有了它,以后【替换所有】就不用写正则了

const str = "today is work will be finished today";
//old
//const newStr = str.replace(/today/g, "tomorrow");
//new
const newStr = str.replaceAll("today", "tomorrow");

(2)Promise.any()
返回第一个 fullfilled 的 promise ,若全部 reject,则返回一个带有失败原因的 AggregateError

(3)数字分隔符
数字分隔符是数字之间添加的下划线;当代码解析时,下划线会被自动去除;

let n1 = 1_000_000_000;
console.log(n1); // This will print: 1000000000

语法点评:写很大的数字可以更容易读。

(4)三个逻辑赋值
+||= 逻辑或赋值,等同于:a || (a = b)
&&= 逻辑与赋值,等同于:a && (a = b)
??= 逻辑合并赋值,等同于:a ?? (a = b)

举栗子:

//当左边为false时赋值
let myPlaylist = {songsCount: 0, songs:[]};
myPlaylist.songsCount ||= 100;
console.log(myPlaylist); // This will print: {songsCount: 100, songs: Array(0)}
//当左边为true时赋值
let myFiles = {filesCount: 100, files:[]};
myFiles.filesCount &&= 5;
console.log(myFiles); // This will print: {filesCount: 5, files: Array(0)}
//当左边为null或者undefined时赋值
let userDetails = {firstname: "Katina", age: 24}
userDetails.lastname ??= "Dawson";
console.log(userDetails); // This will print: {firstname: "Katina", age: 24, lastname: "Dawson"}

点评:运用这哥仨,我们的代码逼格又高了。

八、ES13(es2022)

(1)at()
根据传入的数字获取字符串、数组的元素。不同于[]的是它还可以获取负数,也就是倒数

// 1.数组
const arr = [10, 20, 30, 40];
console.log(arr.at(0)); // 10
// at方法也支持负值
console.log(arr.at(-1)); // 40
// 2.字符串
const message = "Hello";
console.log(message.at(0)); // H
console.log(message.at(-1)); // o

(2)全局await
现在在全局作用域下,可以直接使用await

function setTimeoutAsync(timeout) {
   return new Promise((resolve) => {
   setTimeout(() => {
   resolve();
  }, timeout);
 });
}
// Waits for timeout - no error thrown
await setTimeoutAsync(3000);

语法点评:不建议这么用,可能会阻塞js进程导致变慢。

(3)类允许在constructor外部声明字段

class Car {
  color = "blue";
  age = 2;
}
  const car = new Car();
  console.log(car.color); // blue
  console.log(car.age); // 2

等同于

class Car {
  constructor() {
  this.color = "blue";
  this.age = 2;
 }
}
  const car = new Car();
  console.log(car.color); // blue
  console.log(car.age); // 2

语法点评:在类不需要接收参数,或者不需要调用super关键字时,就可以免写constructor了,且少写一些this 。

(4)类的私有方法和字段
现在可以将私有字段和成员添加到类中,方法是在其前面加上井号 (#),试图从类外部访问它们会导致错误

class Person {
  #firstName = "Joseph";
  #lastName = "Stevens";
 get name() {
  return `${this.#firstName} ${this.#lastName}`;
  }
}
const person = new Person();
console.log(person.name);//Joseph Stevens
console.log(person.#firstName);
console.log(person.#lastName);
// SyntaxError: Private field "#firstName" must be
// declared in an enclosing class

语法点评:如果你需要私藏类的变量,那就派上用场了。

(5)类静态块
ES13 允许在创建类时定义只执行一次的静态块,这类似于其他支持面向对象编程的语言(如 C# 和 Java)中的静态构造函数。

一个类的类主体中可以有任意数量的静态 {} 初始化块,它们将与任何交错的静态字段初始值设定项一起按照声明的顺序执行,我们可以在静态块中使用超属性来访问超类的属性。

class Vehicle {
  static defaultColor = "blue";
}
class Car extends Vehicle {
  static colors = [];
  static {
    this.colors.push(super.defaultColor, "red");
  }
  static {
    this.colors.push("green");
  }
}
console.log(Car.colors); // [ "blue", "red", "green" ]

(6)in 运算符
来检查一个对象中是否有一个特定的私有字段,使用 in 运算符

class Car {
  #color;
  hasColor() {
    return #color in this;
  }
}
class House {
  #color;
  hasColor() {
    return #color in this;
  }
}
const car = new Car();
const house = new House();
console.log(car.hasColor()); // true;
console.log(car.hasColor.call(house)); // false
console.log(house.hasColor()); // true
console.log(house.hasColor.call(car)); // false

(7)Object.hasOwn()
用来检测对象中是否含有指定属性,它接受对象和属性作为参数,返回 true/false。

const obj = { name: "hyl", color: "red" };
console.log(Object.hasOwn(obj, "color")); // true
console.log(Object.hasOwn(obj, "name")); // false
function userAction() {
  try {
    apiCallThatCanThrow();
  } catch (err) {
    throw new Error("New error message", { cause: err });
  }
}
try {
  userAction();
} catch (err) {
  console.log(err);
  console.log(`Cause by: ${err.cause}`);
}

(8)高级捕获错误
错误对象现在有一个 cause 属性,用于指定导致即将抛出的错误的原始错误。这有助于为错误添加额外的上下文信息并帮助诊断意外行为,我们可以通过在作为第二个参数传递给 Error() 构造函数的对象上设置 cause 属性来指定错误的原因。

function userAction() {
  try {
    apiCallThatCanThrow();
  } catch (err) {
    throw new Error("New error message", { cause: err });
  }
}
try {
  userAction();
} catch (err) {
  console.log(`Cause by: ${err.cause}`);
}
//Cause by: ReferenceError: apiCallThatCanThrow is not defined

(9)Array.prototype.findLast()和Array.prototype.findLastIndex()
快速查找到符合条件的最后一项或者下标。与find正相反

const nums = [7, 14, 3, 8, 10, 9];
const lastEven = nums.findLast((num) => num % 2 === 0);
const lastEvenIndex = nums.findLastIndex((num) => num % 2 === 0);
console.log(lastEven); // 10
console.log(lastEvenIndex); // 4
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350