前言
ECMAScript 是一种由 Ecma 国际组织(前身为欧洲计算机制造商协会)标准化的脚本语言,它在 Web 开发中扮演着重要的角色。自 ECMAScript 5(简称 ES5)以来,每一年都会推出新的版本。ES6、ES7、ES8、ES9、ES10 和 ES11 中都有许多令人兴奋的新特性。本文将会介绍每个版本的主要新特性。
ECMAScript 6(ES6)
块级作用域变量声明 let
和 const
ES6 引入了 let
和 const
这两个新的关键字,它们使得 JavaScript 有了真正的块级作用域。let
声明的变量只在当前代码块内有效,而 const
定义的是常量,它通常被用于声明不会改变的变量。
// ES5 var a = 1; if (a) { var b = 2; } console.log(b); // 2 // ES6 let c = 1; if (c) { let d = 2; } console.log(d); // ReferenceError: d is not defined const e = 1; e = 2; // TypeError: Assignment to constant variable.
模板字符串
ES6 引入了一种新的字符串格式,称为模板字符串。它使用反引号 `` 括起来,其中可以包含表达式${expression}
,表达式的值会被自动计算并插入到字符串中。
// ES5 var name = 'Alice'; var url = 'https://example.com/' + name; // ES6 let name = 'Alice'; let url = `https://example.com/${name}`;
解构赋值
解构赋值可以方便地从数组或对象中获取值并赋值给变量。
// ES5 var arr = [1, 2, 3]; var x = arr[0]; var y = arr[1]; var z = arr[2]; // ES6 let [x, y, z] = [1, 2, 3]; // 对象的解构赋值 let person = {name: 'Alice', age: 18}; let {name: pname, age: page} = person; console.log(pname, page); // Alice 18
箭头函数
箭头函数是一种新的函数表达式语法,它比传统的函数表达式更简洁。
// ES5 var sum = function(a, b) { return a + b; } // ES6 let sum = (a, b) => a + b;
类
ES6 引入了一种新的语法用于定义类,它更加易读易写。
// ES5 var Person = function(name) { this.name = name; } Person.prototype.sayHello = function() { console.log('Hello, ' + this.name); } // ES6 class Person { constructor(name) { this.name = name; } sayHello() { console.log(`Hello, ${this.name}`); } }
模块
ES6 引入了一种新的文件级别的模块定义语法,它使得 JavaScript 的模块化开发更加简单和可维护。
// 导出变量 export const PI = 3.141592653589793; // 导出函数 export function square(x) { return x * x; } // 导出类 export class Circle { constructor(radius) { this.radius = radius; } area() { return PI * this.radius * this.radius; } } // 导入模块 import {PI, square, Circle} from './math'; console.log(PI); // 3.141592653589793 console.log(square(2)); // 4 console.log(new Circle(1).area()); // 3.141592653589793
ECMAScript 7(ES7)
Array.prototype.includes
Array.prototype.includes
方法用于判断数组中是否包含某个元素。
let arr = [1, 2, 3]; console.log(arr.includes(2)); // true console.log(arr.includes(4)); // false
指数运算符
ES7 引入了一个新的指数运算符 **
,方便进行乘方运算。
let x = 2 ** 3; // x 等于 8
ECMAScript 8(ES8)
异步函数
异步函数是一种新的函数类型,在函数定义前面加上 async
就可以定义异步函数。
async function f() { let result = await something(); // 等待异步操作完成 // ... }
对象属性的展开
ES8 允许在对象字面量中使用省略符 …
来展开另一个对象的属性。
let obj1 = {x: 1, y: 2}; let obj2 = {z: 3, ...obj1}; console.log(obj2); // {z: 3, x: 1, y: 2}
字符串填充
ES8 引入了字符串的填充方法 padStart()
和 padEnd()
,它们可以用于为字符串添加前缀或后缀并保持其长度不变。
let str = 'foo'; console.log(str.padStart(5, '*')); // **foo console.log(str.padEnd(5, '*')); // foo**
ECMAScript 9(ES9)
异步迭代器
ES9 允许对象实现异步迭代器,需要实现一个异步的 Symbol.asyncIterator
方法。
async function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function* generate() { yield 1; await sleep(1000); yield 2; } (async function() { for await (const value of generate()) { console.log(value); } })();
对象扩展
ES9 引入了一些新的对象扩展语法,包括对象的spread
(...
)和剩余(...rest
)操作符。
let obj1 = {a: 1, b: 2}; let obj2 = {...obj1, c: 3}; console.log(obj2); // {a: 1, b: 2, c: 3} let {a, ...rest} = obj2; console.log(rest); // {b: 2, c: 3}
Promise.prototype.finally
Promise.prototype.finally()
方法是一个无论Promise对象最后状态如何都会执行的函数。
let p = Promise.resolve('foo'); p.finally(() => console.log('finally'));
ECMAScript 10(ES10)
Array.prototype.flat()
Array.prototype.flat()
方法可用于将嵌套的数组展平为一维数组。
let arr1 = [1, [2], [3, [4]]]; console.log(arr1.flat()); // [1, 2, 3, [4]] let arr2 = [1, [2], [3, [4]]]; console.log(arr2.flat(2)); // [1, 2, 3, 4]
Array.prototype.flatMap()
Array.prototype.flatMap()
方法可以像 Array.prototype.map()
一样对数组中的每个元素执行一个函数,并将所有结果展平为一维数组。
let arr = [1, 2, 3]; let result = arr.flatMap(x => [x * 2]); console.log(result); // [2, 4, 6]
可选链语法
ES10 引入了可选链语法 ?.
,用于简化访问对象中特定属性的行为。
let person = { firstName: 'John', lastName: 'Doe' } console.log(person?.middleName?.toLowerCase()); // undefined
ECMAScript 11(ES11)
String.prototype.replaceAll()
String.prototype.replaceAll()
方法可以替换字符串中所有匹配的子字符串。
let str = 'Hello, World!'; console.log(str.replaceAll('o', 'x')); // Hellx, Wxrld!
Promise.allSettled()
Promise.allSettled()
方法返回一个 Promise 对象,该 Promise 在所有的 Promise 解决之后才会解决,并且会收集所有 Promise 对象的结果。
let p1 = Promise.resolve(1); let p2 = Promise.reject('error'); let p3 = Promise.resolve(3); Promise.allSettled([p1, p2, p3]).then(results => { console.log(results); }); // [{status: 'fulfilled', value: 1}, {status: 'rejected', reason: 'error'}, {status: 'fulfilled', value: 3}]
globalThis
在浏览器中,全局对象是 window
,在 Node.js 中,全局对象是 global
,在 web worker 中,全局对象是 self
。ES11 引入了一个新的 globalThis
全局对象,它可以在不同的环境中访问全局作用域。
console.log(globalThis === window); // true in a browser environment console.log(globalThis === global); // true in Node.js environment
总结
随着 ECMAScript 的不断进化,JavaScript 语言不断变得更加强大和灵活。我们应该跟进 ECMAScript 新版本的主要特性,来不断提升我们的开发效率和代码质量。以上是 ES6 到 ES11 的主要特性介绍,希望对大家有所帮助。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a4f0d5add4f0e0ffd4cf5f