从 ES6 到 ES11:JavaScript 版本更新指南
前言
JavaScript 是目前世界上最流行的编程语言之一。随着 Web 应用的不断发展,JavaScript 的语言规范也不断更新改进。自 ECMAScript 2015(也叫 ES6)以来,JavaScript 已经经历了数次版本更新,每次更新都带来了许多新的特性和语法糖。ES11(officially known as ECMAScript 2020)是目前为止最新的 JavaScript 规范,本篇文章将从 ES6 开始,介绍 JavaScript 最新版本的一些新特性和语法糖。
ES6
ES6 是 JavaScript 官方规定的第六版标准,也是最重要和广泛使用的版本之一。ES6 带来了许多新的语言特性,包括箭头函数、解构、let 和 const 等。下面是一些具有代表性的特性介绍。
- 箭头函数
箭头函数(Arrow Function)是一种新的函数定义语法,它使用箭头符号(=>)来代替传统的 function 关键字定义函数。箭头函数通常具有更简洁的语法和更明确的 this 绑定。举个例子,我们可以使用箭头函数来改写一个传统的计算平方的函数:
// 传统方式
function square(x) {
return x * x;
}
// 箭头函数
const square = x => x * x;- 解构
解构(Destructuring)是一种新的变量定义语法,它允许我们将一个对象或数组中的某些属性或元素分解到单独的变量中,方便代码编写和阅读。下面是一些解构的例子:
// www.javascriptcn.com code example
// 解构对象
const person = {name: 'Alice', age: 20};
const {name, age} = person;
console.log(name, age); // Alice 20
// 解构数组
const numbers = [1, 2, 3, 4];
const [first, second, ...rest] = numbers;
console.log(first, second, rest); // 1 2 [3, 4]- let 和 const
let 和 const 是新的变量定义关键字,它们取代了旧的 var 关键字,更好地控制了变量的作用域和声明周期。let 定义的变量是块级作用域,只在定义所在的 {} 内有效,而 const 定义的变量是不可变的,一旦赋值便不能再次修改。举个例子,我们可以使用 let 和 const 来改写一个传统的 for 循环:
// www.javascriptcn.com code example
// 传统方式
for (var i = 0; i < 10; i++) {
// do something
}
console.log(i); // 10
// 新方式
for (let i = 0; i < 10; i++) {
// do something
}
console.log(i); // ReferenceError: i is not defined
const PI = 3.1415926;
PI = 3; // TypeError: Assignment to constant variable.ES7
ES7 是 JavaScript 官方规定的第七版标准,主要添加了两个新的特性:Array.prototype.includes() 和 指数操作符。
- Array.prototype.includes()
Array.prototype.includes() 是一个类方法,它判断一个数组中是否包含某个元素,返回一个布尔类型的值。相比之前的 indexOf() 方法,includes() 可以更方便地检测 NaN 和数组中是否包含 undefined 和 null 等值。下面是示例代码:
const arr1 = [1, 2, 3, 4]; console.log(arr1.includes(2)); // true console.log(arr1.includes(5)); // false const arr2 = ['foo', NaN, undefined, null]; console.log(arr2.includes(NaN)); // true console.log(arr2.includes(undefined)); // true console.log(arr2.includes(null)); // true
- 指数操作符
指数操作符(Exponentiation Operator)是一种新的表达式语法,它用双星号(**)表示计算底数的 n 次方,与 Math.pow() 方法类似。下面是示例代码:
console.log(2 ** 3); // 8 console.log(Math.pow(2, 3)); // 8 const a = 2; a **= 3; console.log(a); // 8
ES8
ES8 是 JavaScript 官方规定的第八版标准,主要添加了三个新的特性:async/await、Object.entries() 和 Object.values()。
- async/await
async/await 是 JavaScript 中处理异步操作的新方法,它使用 async 和 await 关键字来编写更加简洁和易读的异步代码。async 和 await 关键字能让异步代码看起来像是同步代码,更容易阅读和维护。下面是一个使用 async/await 的示例代码:
// www.javascriptcn.com code example
function delay(time) {
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, time);
});
}
async function doSomething() {
console.log('Start');
await delay(1000);
console.log('After 1s');
await delay(1000);
console.log('After 2s');
}
doSomething();- Object.entries() 和 Object.values()
Object.entries() 和 Object.values() 是一对新的静态方法,它们允许我们直接获取一个对象的属性名和属性值组成的数组。Object.entries() 返回的数组包含键值对,Object.values() 返回的数组仅包含属性值。下面是示例代码:
const obj = {name: 'Alice', age: 20};
console.log(Object.entries(obj)); // [['name', 'Alice'], ['age', 20]]
console.log(Object.values(obj)); // ['Alice', 20]ES9
ES9 是 JavaScript 官方规定的第九版标准,主要添加了两个新的特性:异步迭代和 Rest/Spread 属性。
- 异步迭代
异步迭代(Asynchronous Iteration)是一种新的迭代方法,它允许我们在异步代码中进行迭代,且不需要回调或者 promise 的使用。异步迭代需要将迭代器对象的 Symbol.asyncIterator 属性指向一个异步方法,然后使用 for...await...of 循环来进行迭代。下面是示例代码:
// www.javascriptcn.com code example
async function* asyncIterable() {
yield 1;
yield 2;
yield 3;
}
const asyncIterator = asyncIterable();
const asyncForEach = async () => {
for await (const num of asyncIterator) {
console.log(num);
}
};
asyncForEach();- Rest/Spread 属性
Rest/Spread 属性是一种新的对象和数组操作语法,它使用三个连续的点号(...)来表示一个对象或数组的元素。Rest 属性用于取出对象或数组中某些属性或元素,Spread 属性则用于将对象或数组展开成单独的属性或元素。下面是示例代码:
// www.javascriptcn.com code example
// Rest 属性
const person = {name: 'Alice', age: 20, city: 'Shanghai', country: 'China'};
const {name, age, ...rest} = person;
console.log(name, age, rest); // Alice 20 {city: 'Shanghai', country: 'China'}
// Spread 属性
const arr1 = [1, 2];
const arr2 = [3, 4];
const arr3 = [...arr1, ...arr2];
console.log(arr3); // [1, 2, 3, 4]ES10
ES10 是 JavaScript 官方规定的第十版标准,主要添加了几个新的特性:Array.prototype.flat()、Array.prototype.flatMap()、Object.fromEntries() 和 String.prototype.trimStart()/trimEnd()。
- Array.prototype.flat() 和 Array.prototype.flatMap()
Array.prototype.flat() 和 Array.prototype.flatMap() 是两个新的数组操作方法,它们分别用于扁平化一个多维数组和对数组中的每个元素进行映射和展开。Array.prototype.flat() 方法使得使用自带的 flat() 方法可以将多维数组转化为扁平化的一维数组。Array.prototype.flatMap() 方法使用 map() 方法对数组中的每个元素进行操作,然后使用 flat() 方法将嵌套的数组转换为扁平数组,下面是示例代码:
// flat() 示例代码 const arr1 = [1, [2, 3], [[4], 5]]; console.log(arr1.flat()); // [1, 2, 3, [4], 5] // flatMap() 示例代码 const arr2 = [1, 2, 3]; console.log(arr2.flatMap(x => [x * 2])); // [2, 4, 6]
- Object.fromEntries()
Object.fromEntries() 是一个新的静态方法,它将一个由键值对数组组成的二维数组转换为一个对象。该方法与 Object.entries() 方法相对应,使用两个方法可以将对象和二维数组进行相互转换,下面是示例代码:
const entries = [['name', 'Alice'], ['age', 20]];
console.log(Object.fromEntries(entries)); // {name: 'Alice', age: 20}- String.prototype.trimStart()/trimEnd()
String.prototype.trimStart() 和 String.prototype.trimEnd() 是两个新的字符串方法,它们用于去除字符串头部或尾部的空格和制表符。这两个方法分别返回去除空格后的新字符串,下面是示例代码:
const str = ' Hello, World! '; console.log(str.trimStart()); // 'Hello, World! ' console.log(str.trimEnd()); // ' Hello, World!'
ES11
ES11 是 JavaScript 官方规定的第十一版标准,也是目前为止最新的 JavaScript 规范。ES11 增加了几个新的特性,其中包括可选链操作符、Nullish 合并运算符、String.prototype.matchAll() 和 Promise.allSettled()。
- 可选链操作符
可选链操作符(Optional Chaining Operator)是一种新的属性访问语法,它用问号(?)来充当属性访问运算符,避免了访问不存在属性的错误。如果属性不存在,那么该运算符返回 undefined。下面是示例代码:
const person = {name: 'Alice', address: {city: 'Shanghai'}};
console.log(person.address?.city); // 'Shanghai'
console.log(person.address?.country); // undefined- Nullish 合并运算符
Nullish 合并运算符(Nullish Coalescing Operator)是一种新的逻辑运算符,它用两个问号(??)充当或运算符,其效果是当左侧的表达式值是 null 或 undefined 的时候,才会对右侧表达式求值。下面是示例代码:
const a = null ?? 'default'; // 'default' const b = 0 ?? 'default'; // 0
- String.prototype.matchAll()
String.prototype.matchAll() 是一个新的正则表达式方法,它能够在一个字符串中搜索全部匹配的子串,返回一个迭代器。迭代器包含了每个子串的匹配对象(包括匹配到的子串、索引等)。下面是示例代码:
const str = 'Hello World! Nice to meet you.';
const re = /[A-Z]/g;
const matches = str.matchAll(re);
for (const match of matches) {
console.log(match);
}- Promise.allSettled()
Promise.allSettled() 是一个新的 Promise 方法,它接收一个可迭代对象,返回一个新的 Promise 对象。当所有 Promise 对象状态都已经变成 settled 状态的时候,该 Promise 对象才会 resolve,并返回所有状态结果的数组。下面是示例代码:
// www.javascriptcn.com code example
const promises = [
Promise.resolve('one'),
Promise.reject('two'),
Promise.resolve('three'),
];
Promise.allSettled(promises).then(results => console.log(results));
/*
[
{ status: "fulfilled", value: "one" },
{ status: "rejected", reason: "two" },
{ status: "fulfilled", value: "three" }
]
*/结尾
ES6 到 ES11,JavaScript 规范逐渐得到了更完善和丰富的更新。尽管新特性的引入经常伴随着一定的学习成本和代码兼容性问题,但我们可以从中发现,这些新特性和语法糖都能够帮我们更加高效地编写代码,提高代码运行效率和可维护性。在实际项目中,我们需要结合业务需求和技术栈特点,选择合适的代码编写方式,充分利用 JavaScript 最新版本的更新。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d6a082a941bf7134c68a64