JavaScript进阶(二十六):ES各版本特性详解

这篇具有很好参考价值的文章主要介绍了JavaScript进阶(二十六):ES各版本特性详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、ECMAScript简介

ECMAScript是一种由Ecma国际(前身为欧洲计算机制造商协会,European Computer Manufacturers Association)通过ECMA-262标准化的脚本程序设计语言。这种语言在万维网上应用广泛,它往往被称为JavaScriptJScript,所以它可以理解为是JavaScript的一个标准,但实际上后两者是ECMA-262标准的实现和扩展。

二、ES6 (ES2015)

  1. Class

  2. 模块化语法(importexport

  3. 箭头函数 () => {…},是函数的缩写。

  4. 函数参数默认值

function fn(x,y='World') {
   console.log(x, y);
}
  1. 模板字面量
    之前实现中,长字符串的组合是通过 + 号来连接的。
    它的可读性很差,使用模板字符串,它更容易阅读。

  2. 解构赋值
    允许 JavaScript 轻松地从数组和对象中获取内容。

  3. 扩展运算符
    它是用三点(...)表示,Array是可以扩展的,如果是Object,会按照key-value进行扩展。

  4. 对象属性简写
    如果构成对象的字段名称与前面段落中的变量相同,则可以省略该值,看起来更流线型。

  5. Promise
    Promise 是一种异步(非同步)写法的解决方案,比原来的回调写法更加优雅。ES8(ES2017)发布了更完美的async,await,直接让异步写得像同步一样。缺点是当思路落到复杂的业务逻辑上时,有时会错过await,在运行时发生错误。

  6. let, const 替换 var

  • let:通用变量,可以被覆盖。
  • const:一旦声明,其内容不可修改。因为数组和对象都是指针,所以它们的内容可以增加或减少, 但不改变其指针。

早期,JavaScriptvar作用域是全局的。也就是说,var变量是在使用后声明的,执行的时候会自动提到顶层,后面会赋值。
更容易受到污染。

三、ES7 (ES2016)

  1. Array.prototype.includes()
    用于判断数组是否包含指定值,如果是,则返回true;否则,返回假。和之前indexOf的用法一样,可以认为是返回一个布尔值,语义上更加清晰。
  2. 幂运算符 console.log(2**10); // 1024

四、ES8 (ES2017)

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

  2. Object.values()
    返回对象自身属性的所有值,不包括继承的值。

  3. Object.entries()
    返回可枚举键,即传入对象本身的值。

  4. 字符串 padStart() & padEnd()
    你可以在字符串的开头或结尾添加其他内容,并将其填充到指定的长度。
    过去,这些功能通常是通过通用的辅助工具包(如 lodash)引入的,并将它们放在一起。

  5. 尾随逗号
    允许在函数参数列表末尾使用逗号。

  6. Object.getOwnPropertyDescriptors()
    获取你自己的描述符,一般的开发业务需求通常不会用到。

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

  8. Atomics object
    Atomics 对象,它提供了一组静态方法来对 SharedArrayBuffer 执行原子操作。原子的所有属性和函数都是静态的。

如果一个多线程同时在同一个位置读写数据,原子操作保证了正在操作的数据如预期的那样:即在上一个子操作结束后执行下一个,操作不中断。可以说是针对Node.Js中多线程Server的开发而加强的功能,在前端开发中使用的机会相当低。chrome 已经提供了支持。

五、ES9 (ES2018)

  1. 循环等待
    在异步函数中,有时需要在同步 for 循环中使用异步(非同步)函数。
async function process(array) {
  for (const i of array) {
    await doSomething(i);
  }
}

async function process(array) {
  array.forEach(async i => {
    await doSomething(i);
  });
}

上面的代码不会像预期的那样输出期望的结果。

for循环本身还是同步的,会在循环中的异步函数完成之前执行整个for循环,然后将里面的异步函数逐一执行。

ES9 增加了异步迭代器,允许 awaitfor 循环一起使用,逐步执行异步操作。

async function process(array) {
  for await (const i of array) {
    doSomething(i);
  }
}
  1. promise.finally()
    无论是成功(.then())还是失败(.catch()),Promise 后面都会执行的部分。

  2. Rest, Spread
    在 ES2015 中,Rest 不定长度参数…,可以转换成数组传入。

  3. 正则表达式组
    RegExp 可以返回匹配的数据包

const regExpDate = /([0-9]{4})-([0-9]{2})-([0-9]{2})/;
const match      = regExpDate.exec('2020-06-25');
const year       = match[1]; // 2020
const month      = match[2]; // 06
const day        = match[3]; // 25
  1. 正则表达式 dotAll
    . 表示匹配除输入以外的任何符号,添加这些标志后,允许匹配输入。
/hello.world/.test('hello\nworld');  // false
/hello.world/s.test('hello\nworld'); // true

六、ES10 (ES2019)

  1. 更友好的 JSON.stringify
    如果输入是 Unicode 但超出范围,则 JSON.stringify 最初会返回格式错误的 Unicode 字符串。

现在是第 3 阶段的提案,使其成为有效的 Unicode 并以 UTF-8 呈现。

  1. Array.prototype.flat() & Array.prototype.flatMap()
    展平阵列

  2. String.prototype.trimStart() & String.prototype.trimEnd()
    trimStart() 方法从字符串的开头删除空格,trimLeft() 是此方法的别名。

  3. Object.fromEntries()
    Object.fromEntries() 方法将键值对列表转换为对象。

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

  5. fixed catch 绑定
    在使用catch之前,不管有用与否,一定要传入一个eparameter来表示接收到的错误。
    如果现在不用,可以省略。

  6. BigInt(新数字类型)(重要)
    BigInt 值,有时也称为 BigInt,是一个 bigint 原语,通过将 n 附加到整数文字的末尾,或通过调用 BigInt() 函数(没有 new 运算符)并给它一个整数值或字符串来创建值。

  • ES5:String, Number, Boolean, Null, Undefined
  • ES6 新增:Symbol,到ES6就一共有6 种类型
  • ES10 新增:BigInt,就达到 7 种类型

七、ES11 (ES2020)

  1. Promise.allSettled()
    Promise.allSettled() 方法返回一个在所有给定的 Promise 都已实现或拒绝后实现的 Promise,并带有一组对象,每个对象都描述了每个 Promise 的结果。

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

相比之下,Promise.all() 返回的 Promise 可能更合适,如果任务相互依赖/如果想立即拒绝其中任何一个拒绝。

  1. 可选链操作符?.

在开发中,很容易遇到先判断数据是否存在,判断是否写入。

const isUserExist = user && user.info;
if (isUserExist) { 
    username = user.info.name; 
}

如果返回的数据为null或者用户对象下没有相应属性,则会抛出Uncaught TypeError: Cannot read property...

导致程序无法继续执行

使用 ?.,语法更简单

const username = user?.info?.name;

如果存在,获取name的值,如果不存在,赋值undefined

|| 一起使用,只需一行!

const username = user?.name || 'guest';
  1. Nullish 合并运算符 ??
    JavaScript中,遇到0、nullundefined时会自动转为false
    但有时0其实是一个正常的值,只能容错undefinednull,但是使用??,可以保持简洁。

  2. Dynamic-import
    从字面上看,应该很容易理解,就是在需要的时候加载相关的逻辑。

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

八、ES12 (ES2021)

  1. Promise.any()
    Promise.any() 接受一个可迭代的 Promise 对象。它返回一个单一的 Promise,只要 iterable 中的任何一个 Promise 完成,就会返回一个 Promise,并带有已完成的 Promise 的值。

如果可迭代的实现中没有任何承诺(如果所有给定的承诺都被拒绝),则返回的承诺会被 AggregateError 拒绝,AggregateErrorError 的一个新子类,它将单个错误组合在一起。

  1. 逻辑赋值运算符
    在开发过程中,可以使用 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
  1. WeakRef
    WeakRef 对象包含对对象的弱引用,该对象称为其目标或引用对象。对对象的弱引用是不会阻止对象被垃圾收集器回收的引用。相反,普通(或强)引用将对象保存在内存中,当一个对象不再有任何强引用时,JavaScript 引擎的垃圾收集器可能会销毁该对象并回收其内存。如果发生这种情况,将无法再从弱引用中获取对象。

九、ES13 (ES2022)

ES13 带来了 6 个新特性:

  • 模块顶层作用域支持 await 表达式。
  • 新增私有类元素(#)、静态块;in 操作符支持私有类元素。
  • 正则新增 d 标志和其对应的 hasIndices 属性,提供了获取捕获组开始索引和结束索引的方法。
  • Error 实例增加 cause 属性,可携带更多错误信息。
  • StringsArraysTypedArrays 新增 at 方法,支持关联访问。
  • Object.hasOwn 代替 Object.prototype.hasOwnProperty,判断对象是否含有属性。

9.1 Strings、Arrays、TypedArrays 的 at 方法

利用下标访问数组元素时,下标会被转换为字符串,负数下标也对应着一个独立的数组元素,所以 Js 的数组是不支持关联访问的。ES13 新增了 at 方法,可以利用负数索引进行关联访问,例如以下示例,可以利用 at 方法和负数索引 -2 来访问倒数第二个元素。

const array = [5, 12, 8, 130, 44];

array.at(-2); // 130

9.2 私有类元素

在类的定义中,以 “#” 开头的标识符为私有标识符,由私有标识符定义的类元素被称为私有类元素,私有类元素只能在类中才能被访问到。类的属性、静态属性、方法、静态方法、访问器、静态访问器都可以被定义为私有类元素。示例代码如下:

class ClassA {
    // 私有属性
    #privateProperty;

    // 静态私有属性
    static #privateStaticProperty;

    // 静态私有 Getter
    static get #privateStaticGet() {
        return 'private-static-get';
    }

    // 静态私有 Setter
    static set #privateStaticSet(val) {
    }

    // 静态私有方法
    static #privateStaticMethod() {
        return 'private-static-method'
    }

    constructor(propertyValue) {
        // 初始化私有属性
        this.#privateProperty = propertyValue;
    }

    // 私有 Get
    get #privateGet() {
        return 'private-get'
    }

    // 私有 Set
    set #privateSet() {
    }

    // 私有方法
    #privateMethod() {
        return 'private-method'
    }
}

在类的内部可以正常访问私有类元素,在类的外部访问私有类元素会抛出句法错误。

class ClassA {
    // 私有属性
    #privateProperty;

    constructor(property, privateProperty) {
        this.property = property;
        this.#privateProperty = privateProperty;
    }

    // 在方法中访问私有属性
    getPrivateProperty() {
        return this.#privateProperty;
    }
}

const instance = new ClassA('property', 'private-property');

instance.property; // 'property'
instance.#privateProperty; // Uncaught SyntaxError: Private field '#privateProperty' must be declared in an enclosing class
instance.getPrivateProperty(); // 'private-property'

以上就是私有类元素的用法,它有效隔离了类内外的数据和逻辑,进一步增强了封装的效果,使程序更加健壮。

9.3 静态块

静态块提供了更加灵活的静态类元素初始化渠道,可以在静态块中使用一系列的语句来完成静态类元素的初始化。可以利用 this 在静态块中访问类的其他静态属性(包括私有属性)。

class ClassA {
    // 静态属性
    static staticProperty;

    // 静态块初始化静态属性,捕捉错误
    static {
        try {
            this.staticProperty = getStaticProperty();
        } catch {
            console.log('Error');
        }
    }
}

当一个类具有多个静态块时,它们会按照定义的顺序进行执行。

class ClassA {
    // 静态属性 A
    static staticPropertyA;

    // 静态块 A
    static {
        this.staticPropertyA = 'static-block-a';
        console.log('static-block-a');
    }

    // 静态属性 B
    static staticPropertyB;

    // 静态块 B
    static {
        this.staticPropertyB - 'static-block-b';
        console.log('static-block-b');
    }
}

// 输出
// static-block-a
// static-block-b

当一个类具有父类时,会先执行父类的静态块,再执行子类的静态块。可以利用 super 在子类的静态块中访问父类的属性。

// 父类
class ParentClass {
    // 父类属性
    static parentProperty;

    // 父类静态块
    static {
        this.parentProperty = 'parent-property';
        console.log('parent-static-block');
    }
}

// 子类
class ChildClass extends ParentClass {
    // 子类静态块
    static {
        console.log(super.parentProperty);
        console.log('child-static-block');
    }
}

// 输出
// parent-static-block
// parent-property
// child-static-block

9.4 私有 in 操作符

in 操作符可以判断实例中是否存在属性,当新增了私有化类元素后,也可以和下面例子一样,在类定义内使用 in 操作符判断私有化类元素存在与否。

class ClassA {
    // 私有属性
    #privateProperty;

    // 利用 in 操作符判断私有属性是否存在
    static hasPrivateProperty(instance) {
        return #privateProperty in instance
    }

    constructor(privateProperty) {
        this.#privateProperty = privateProperty;
    }
}

const instance = new ClassA('private-property');
ClassA.hasPrivateProperty(instance);

// 输出
// true

9.5 正则 /d 标志

正则表达式通常用来处理字符串,正则表达式有很多标志,它决定了正则状态机的行为和输出结果。ES13 新增的 d 标志对应正则实例的 hasIndices 属性,当设置 d 标志时,hasIndicestrue 。使用 d 标志后,正则表达式的匹配结果将包含每个捕获组捕获子字符串的开始和结束游标。

// 字符串
const str = "today is saturday";

// 正则表达式
const reg = /saturday/d;

// 匹配结果输出游标
const [start, end] = reg.exec(str).indices[0];

console.log([start, end]); // [9, 17]

9.6 Error 对象的 cause 属性

在以往 Error 对象只能传递消息信息,现在 ES13 为 Error 增添了 cause 属性,它可以是任意数据类型,方便获取更多地错误信息。

try {
    // 抛出带 cause 属性的 Error实例
    throw new Error('faied message', { cause: 'cause' });
} catch (error) {
    // 捕获 error 并输出 cause
    console.log(error.cause)
}

// 输出
// cause

9.7 Object.hasOwn

ES13 新增了 Object.hasOwn 方法判断这个实例上是否有属性,以代替之前的 Object.prototype.hasOwnProperty 方法。文章来源地址https://www.toymoban.com/news/detail-724229.html

const object = {
    count: 1
};

Object.hasOwn(object, 'count'); // true
Object.hasOwn(object, 'toString'); // false
Object.hasOwn(object, 'property'); // false

十、拓展阅读

  • 《JavaScript进阶(十四):详解 ES6 中的 export 和 import》
  • 《JavaScript进阶(十三):JavaScript 空值合并运算符、可选链操作符、空值赋值运算符讲解》
  • 《JavaScript进阶(十二):JS 模块化编程规范-CommonJS、AMD、CMD、ES6》
  • 《JavaScript进阶(十八):ES6 Symbol 用法》
  • 《JavaScript进阶(二十):精解 ES6 Promise 用法》
  • 《JavaScript进阶(二十四):ES8 中 async 与 await 使用方法详解》
  • 《JavaScript进阶(二十五):Promise 详解》

到了这里,关于JavaScript进阶(二十六):ES各版本特性详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JavaScript版本ES5/ES6及后续版本

    Brendan Eich在短短10天内创建了JavaScript的第一个版本。它被称为摩卡,但已经具备了现代JavaScript的许多基本特性! 为了吸引Java开发人员,Mocha先是更改为LiveScript,然后又更改为JavaScript然而,JavaScript与Java几乎没有任何关系; 微软推出了IE,从网景复制JavaScript,并称之为JScript; 由

    2024年02月13日
    浏览(48)
  • 软件工程师,学习下JavaScript ES6新特性吧

    概述         作为一名软件工程师,不管你是不是前端开发的岗位,工作中或多或少都会用到一点JavaScript。JavaScript是大家所了解的语言名称,但是这个语言名称是Oracle公司注册的商标。JavaScript的正式名称是ECMAScript。1996年11月,JavaScript的创造者网景公司将JS提交给国际化

    2024年02月13日
    浏览(46)
  • 【JavaScript解析】ES6定义变量与箭头函数详解

    箭头函数可以说是ES6的一大亮点,使用箭头函数,可以简化编码过程,使代码更加的简洁 本文由千锋前端老师独家创作,主要给大家介绍了关于ES6中箭头函数的相关资料,文中通过实例代码介绍的非常详细,觉得有帮助的话可以【关注】持续追更~ 我们现在知道定义(声明)一个变

    2024年02月05日
    浏览(48)
  • javascript基础二十六:JavaScript中如何实现函数缓存?有哪些应用场景?

    一、是什么 函数缓存,就是将函数运算过的结果进行缓存 本质上就是用空间(缓存存储)换时间(计算过程) 常用于缓存数据计算结果和缓存对象 缓存只是一个临时的数据存储,它保存数据,以便将来对该数据的请求能够更快地得到处理 二、如何实现 实现函数缓存主要依

    2024年02月07日
    浏览(92)
  • 学C的第二十六天【指针的进阶(二)】

    ========================================================================= 相关代码gitee自取 :C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 学C的第二十五天【指针的进阶(一)】_高高的胖子的博客-CSDN博客  ================================

    2024年02月13日
    浏览(76)
  • ES新特性系列(一)—— ES的简介与ES6

          前几天在BOSS上了解现在的前端工作的情况和各个公司要求的技术栈情况,看到一条非常有意思的要求:“能够理解并使用ES6、ES7、ES8、ES9、ES10新特性,都2024年了你总不能只知道ES6吧?”       各位彦祖现在现在就回忆一下,自己是否能把上述的ES系列的常用新特性都

    2024年04月29日
    浏览(33)
  • ES6、ES7、ES8、ES9、ES10、ES11、ES12都增加了哪些新特性?

    前端开发的都知道,JavaScript经历了不同标本的迭代,从1到12的不断完善中会添加不同的新特性来解决前一个阶段的瑕疵,让我们开发更加便捷与写法更加简洁! 我记得我第一次接触js的时候是从大学的《21天精通JavaScript》,名字很好听,但是现在还在学,还没有精通!哈哈哈

    2024年02月16日
    浏览(40)
  • Jmeter(二十六)、详解jmeter函数和变量

    详解JMeter函数和变量(1) JMeter函数可以被认为是某种特殊的变量,它们可以被采样器或者其他测试元件所引用。函数调用的语法如下: ${__functionName(var1,var2,var3)}  其中,__functionName匹配被调用的函数名称。用圆括号包含函数的形参,例如${__time(YMD)},不同函数要求的参数也不

    2024年02月11日
    浏览(40)
  • ES6 新特性

    🎄欢迎来到@边境矢梦°的csdn博文🎄  🎄本文主要梳理前端技术的JavaScript的知识点ES6 新特性文件上传下载🎄 🌈我是边境矢梦°,一个正在为秋招和算法竞赛做准备的学生🌈 🎆喜欢的朋友可以关注一下 🫰🫰🫰 ,下次更新不迷路🎆  Ps: 月亮越亮说明知识点越重要 (重要

    2024年02月10日
    浏览(43)
  • ES6新特性

    1、初识ES6 ECMAScript 6.0(简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言;   ECMAScript是JavaScript的规范,而JavaScript是ECMAScript的实现;   ES6是一个历史名词,泛指 5.1 版本后

    2024年02月07日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包