只知道ECMAScript 2015(ES6),一篇汇总ECMAScript 2015~ECMAScript 2023新特性

前言

我们常说的ES6也就是ECMAScript 2015是在2015年6月发布的。这个版本引入了许多重要的语言特性和改进,对 JavaScript 进行了深刻的扩展和升级,ES6 是 JavaScript 语言的一个里程碑。所以有时也被称为ES6。这是由于规范的发布年份与实际版本号之间的不匹配。然而,标准化组织决定更改命名方式,以便更好地反映年份,从而引入了“ECMAScript [年份]”的命名习惯。

从2015年的ECMAScript 2015(ES6)到现在的ECMAScript 2023。在这几年的发展中,我们见证了JavaScript的成为web开发的主导语言。但是人们在谈论JS时还是习惯性说ES6,然而举例2015已经过去了8年,是不是该更新一下知识库啦。

这篇文章我们介绍一下JavaScript从ES6到ES2023的重要变化。

ECMAScript 2015

这里只介绍一些主要的特性,

  1. let 和 const 声明: 引入了块级作用域的变量声明方式。let用于声明变量,而const用于声明常量。

  2. 箭头函数: 提供了更简洁的函数声明语法,尤其适用于匿名函数。

    // 传统函数
    function add(a, b) {
      return a + b;
    }
    
    // 箭头函数
    const add = (a, b) => a + b;
    
  3. 模板字符串: 允许在字符串中插入表达式,更易读且更灵活。

    const name = 'World';
    const greeting = `Hello, ${name}!`;
    
  4. 默认参数值: 允许在函数声明中为参数设置默认值。

    function greet(name = 'World') {
      console.log(`Hello, ${name}!`);
    }
    
  5. 解构赋值: 允许从数组或对象中提取值并赋给变量。

    // 数组解构
    const [a, b] = [1, 2];
    
    // 对象解构
    const { x, y } = { x: 1, y: 2 };
    
  6. 类和继承: 引入了更接近传统面向对象编程的类和继承语法。

    class Animal {
      constructor(name) {
        this.name = name;
      }
    
      speak() {
        console.log(`${this.name} makes a sound.`);
      }
    }
    
    class Dog extends Animal {
      speak() {
        console.log(`${this.name} barks.`);
      }
    }
    
  7. 模块化: 引入了模块系统,允许将代码分割为可维护的模块。

    // 导出
    export const myVar = 42;
    
    // 导入
    import { myVar } from './myModule';
    
  8. Promise: 提供了更强大的异步编程机制,以解决回调地狱问题。

    const myPromise = new Promise((resolve, reject) => {
      // 异步操作
      if (/* 操作成功 */) {
        resolve('Success!');
      } else {
        reject('Failure!');
      }
    });
    
    myPromise.then(result => console.log(result))
              .catch(error => console.error(error));
    
  9. for…of 和 for…in: 用于迭代对象和数组中的元素。

  10. Set和 Mapz:
    Set 是一种用于存储唯一值的集合。它不允许重复的元素,并提供了一系列方法来操作这些值。

const uniqueNumbers = new Set([1, 2, 3, 1, 2]);

uniqueNumbers.add(4);
console.log(uniqueNumbers); // Set { 1, 2, 3, 4 }

console.log(uniqueNumbers.has(2)); // true

Map 是一种键值对的集合,其中的键和值可以是任意数据类型。它提供了一种更灵活的方式来存储和检索数据,相较于对象,Map 在处理键值对的场景中更为直观和高效。

const userMap = new Map();

userMap.set('name', 'John');
userMap.set('age', 30);

console.log(userMap.get('name')); // 'John'
console.log(userMap.has('gender')); // false

ECMAScript 2016

ECMAScript 2016本质上是一个较小的更新,其中包括了一些相对较小的语法和功能改进。

  1. 指数操作符(Exponentiation Operator): 引入了指数操作符 **,用于计算一个数字的幂。

    let result = 2 ** 3; // 8
    
  2. Array.prototype.includes(): 在数组原型上添加了 includes 方法,用于检查数组是否包含特定元素。

    const array = [1, 2, 3];
    console.log(array.includes(2)); // true
    console.log(array.includes(4)); // false
    

ECMAScript 2017

ECMAScript 2017(也称为ES8)是在2017年发布的 JavaScript 语言的一个版本,相对于 ECMAScript 2016 来说,引入了一些新的功能和改进。以下是其中一些主要的变化:

  1. 异步函数(Async/Await)的改进: ES2017 对异步函数进行了一些改进,使其更加灵活和强大。异步函数是使用 async 关键字声明的函数,而 await 关键字可以在异步函数内部等待一个 Promise 解决。

    async function fetchData() {
      let response = await fetch('https://api.example.com/data');
      let data = await response.json();
      return data;
    }
    
  2. Object.values() 和 Object.entries(): 引入了 Object.values()Object.entries() 方法,分别用于获取对象的值数组和键值对数组。

    const obj = { a: 1, b: 2, c: 3 };
    
    console.log(Object.values(obj)); // [1, 2, 3]
    console.log(Object.entries(obj)); // [['a', 1], ['b', 2], ['c', 3]]
    
  3. 字符串填充方法(String Padding): 引入了字符串填充方法 String.prototype.padStart()String.prototype.padEnd(),用于在字符串前或后填充指定的字符。

    let str = 'hello';
    console.log(str.padStart(8, '*')); // '***hello'
    console.log(str.padEnd(8, '*')); // 'hello***'
    
  4. 共享内存与原子操作(Shared Memory and Atomics): 引入了 SharedArrayBuffer 和 Atomics 对象,用于更好地支持多线程和并行编程。

    // 创建共享内存
    const buffer = new SharedArrayBuffer(16);
    
    // 在共享内存上进行原子操作
    Atomics.add(new Int32Array(buffer), 0, 5);
    

ECMAScript 2019

也不是每一年都有那种很重要的改变,这里ECMAScript 2018 并入了 ECMAScript 2019

  1. Array.prototype.flat() 和 Array.prototype.flatMap(): 引入了 flatflatMap 方法,用于扁平化嵌套的数组结构。

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

    flatMap 可以同时扁平化和映射数组。

  2. Object.fromEntries(): 提供了从键值对数组创建对象的方法。

    const entries = [['a', 1], ['b', 2], ['c', 3]];
    const obj = Object.fromEntries(entries); // {a: 1, b: 2, c: 3}
    
  3. String.prototype.trimStart() 和 String.prototype.trimEnd(): 引入了字符串的两个新方法,用于删除字符串开头和结尾的空格。

    const str = '   Hello   ';
    console.log(str.trimStart()); // 'Hello   '
    console.log(str.trimEnd()); // '   Hello'
    
  4. Symbol.prototype.description: 允许通过 Symbol.prototype.description 获取 Symbol 的描述信息。

    const mySymbol = Symbol('My Symbol');
    console.log(mySymbol.description); // 'My Symbol'
    
  5. Function.prototype.toString() 的改进: Function.prototype.toString() 方法现在返回精确的源代码表示,包括空格和注释。

    function example() {
      // This is a comment
      return 'Hello';
    }
    
    console.log(example.toString());
    // 函数源代码中包含注释和缩进
    

ECMAScript 2020

ECMAScript 2020(也称为ES11)引入了一些新的功能和改进。以下是其中一些主要的变化:

  1. 可选链操作符(Optional Chaining): 引入了可选链操作符(?.),用于简化访问可能不存在的属性或方法的代码。

    const user = {
      address: {
        street: '123 Main St'
      }
    };
    
    // 传统方式
    const street = user && user.address && user.address.street;
    
    // 使用可选链操作符
    const street = user?.address?.street;
    
  2. 空值合并操作符(Nullish Coalescing Operator): 引入了空值合并操作符(??),用于提供默认值,但仅在变量为 nullundefined 时。

    const defaultValue = 'Default';
    const userValue = null;
    
    // 传统方式
    const result = userValue !== null && userValue !== undefined ? userValue : defaultValue;
    
    // 使用空值合并操作符
    const result = userValue ?? defaultValue;
    
  3. 全局对象 globalThis: 引入了 globalThis,它提供了一种标准的方式来获取全局对象,无论代码在哪里执行(浏览器、Node.js、Web Workers等)。

    console.log(globalThis === window); // 在浏览器中为 true
    console.log(globalThis === global); // 在 Node.js 中为 true
    
  4. Promise.allSettled(): 引入了 Promise.allSettled() 方法,它接收一组 Promise,无论这些 Promise 是成功还是失败,都会等待它们全部 settled(已完成,不论是 resolved 还是 rejected)。

    const promises = [Promise.resolve('Success'), Promise.reject('Error')];
    
    Promise.allSettled(promises)
      .then(results => console.log(results));
    
  5. 动态导入: 可以将js文件动态导入模块中。

  6. BigInt: js代码可以使用更大的整数。

  7. matchAll: 是一个用于 String 的新的方法,和正则相关。这个方法将返回一个迭代器,该迭代器一个接一个地返回所有匹配的组。

ECMAScript 2021

  1. String.prototype.replaceAll: 新增了字符串方法,可以全局替换字符串中的匹配项。
const originalString = 'apple banana apple orange';

// 使用 replaceAll 替换所有的 'apple' 为 'grape'
const newString = originalString.replaceAll('apple', 'grape');

console.log(newString);
// 输出: 'grape banana grape orange'

  1. 逻辑赋值运算符: 引入了逻辑赋值运算符,如&&=、||=和??=,用于对变量进行逻辑运算和赋值的组合操作。
let x = 1;

// 逻辑与赋值
x &&= 2;  // x = x && 2;

let y = 0;

// 逻辑或赋值
y ||= 3;  // y = y || 3;

let z = null;

// 空值合并赋值
z ??= 4;  // z = z !== null && z !== undefined ? z : 4;

  1. 数字分隔符: 允许在数字中使用下划线作为分隔符,以提高数字的可读性。
const billion = 1_000_000_000;
const binary = 0b1010_0010_0011;
const decimal = 1_000_000.123_456;

  1. Promise.any: 新增了Promise的静态方法,接受一个Promise可迭代对象,返回第一个解决的Promise的值。
const promise1 = new Promise((resolve, reject) => setTimeout(resolve, 1000, 'one'));
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 500, 'two'));
const promise3 = new Promise((resolve, reject) => setTimeout(resolve, 800, 'three'));

Promise.any([promise1, promise2, promise3])
  .then(result => console.log(result))
  .catch(error => console.error(error));

  1. WeakRef: 引入了WeakRef和FinalizationRegistry API,用于处理弱引用和对象的最终化
let obj = { data: 'some data' };
let weakRef = new WeakRef(obj);

console.log(weakRef.deref()); // { data: 'some data' }

obj = null; // 弱引用不会阻止对象被垃圾回收

console.log(weakRef.deref()); // undefined

ECMAScript 2022

顶层 await

在 ECMAScript 2022 中引入了顶层 await,它允许在模块的顶层直接使用 await 关键字,而不需要在异步函数内部包裹。

// 在模块的顶层直接使用 await
const result = await fetchData();

console.log(result);

ECMAScript 2023

今年6月份发布了ECMAScript 2023,这将是目前最新版本的规范。

  1. findLast() 、findLastIndex(): 在 JS中,可以通过 find() 和 findIndex() 从前往后查找数组中的值。
    这两个方法支持从后往前查找,用法和find()、findIndex()一样。
const array = [{v: 1}, {v: 2}, {v: 3}, {v: 4}, {v: 5}];

array.findLast(elem => elem.v > 3); // {v: 5}
array.findLastIndex(elem => elem.v > 3); // 4
array.findLastIndex(elem => elem.v > 5); // undefined

2.Hashbang 语法:
Hashbang(也称为 shebang)是一种在脚本文件的开头使用 #! 注释的语法,通常用于指定脚本文件的解释器。

#!/usr/bin/env node
  1. toReversed()、toSorted()、toSpliced()、with()
    之前js支持的reverse、sort、splice都是修改原数组的,以前使用这些方法想又不改变原数组,可能是这样:
const originalArray = [3, 1, 4, 1, 5, 9];

const reversedArray = originalArray.slice().reverse();
const sortedArray = originalArray.slice().sort();
const splicedArray = originalArray.slice(1, 4);
const arrayWithElement = [...originalArray, 7];

console.log(reversedArray); // 输出 [9, 5, 1, 4, 1, 3]
console.log(sortedArray);   // 输出 [1, 1, 3, 4, 5, 9]
console.log(splicedArray);  // 输出 [1, 4, 1]
console.log(arrayWithElement); // 输出 [3, 1, 4, 1, 5, 9, 7]

然而有以下这些方法返回新的数组,不改变原数组。是不是就简便多了。

  • toReversed():返回数组的逆序副本。
  • toSorted():返回数组的排序副本。
  • toSpliced():返回对数组进行切片后的副本。
  • with():可能是返回包含特定元素的副本。

with():该方法会以非破坏性的方式替换给定 index 处的数组元素,即 arr[index]=value 的非破坏性版本。

const arr = ['a', 'b', 'c'];
const arr1 = arr.with(2, 'd');
console.log(arr1); // ['a','b','d']
console.log(arr); // ['a', 'b', 'c']

今天就介绍这些吧,本文介绍并非全部新特性。
注意使用这些方法时看一下浏览器各个版本兼不兼容哦!!!

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值