前言
JavaScript 作为一门非常活跃的编程语言,其标准不断在更新演进,不同版本之间新增的语法和 API 功能也让它的应用范围越来越广泛。本篇文章将详细介绍 JavaScript ES5、ES6、ES7、ES8 四个版本所新增的特性,帮助读者更好的了解 JavaScript 语言的最新动态。
ES5(2009 年发布)
ES5 是目前在许多浏览器中默认支持的 JavaScript 版本,其新增的特性包括以下几个部分:
严格模式(Strict Mode)
在 ES5 中引入了一个新的严格模式,通过向 JavaScript 代码顶部添加 "use strict"; 即可开启严格模式。严格模式的目的是提供一种更安全、更优化的 JavaScript 编写方式,它会使原有的一些不规范写法无法使用,同时还会引入一些新的、更加准确的语义。
举个例子,严格模式中禁止使用不严谨的定义了多个变量的 var 声明方式,而是要使用在每个变量前分别标注 var 的语法,如下所示:
// 不严谨的声明方式 var a = 10, b = 20, c = 30; // 使用严格模式的声明方式 var a = 10; var b = 20; var c = 30;
此外,还有一些其他的限制,比如严格模式中的 this 关键字无法指向全局对象,必须指向函数内部。
新增方法
Array.prototype.forEach()
Array.prototype.forEach() 是一种新的循环方法,它可以循环数组中的每个元素并对其进行处理。其中,第一个参数是一个函数,该函数会接受数组的每个值作为参数,然后进行处理。此外,该方法还可以接受第二个参数,该参数指定了函数执行时的 this 对象。
举个例子,我们可以使用 forEach() 方法循环输出一个数组:
var arr = [1, 2, 3, 4, 5];
arr.forEach(function(item) {
console.log(item);
});Date.now()
Date.now() 是一个用于获取当前时间戳的静态方法,可以替代 new Date().getTime() 和 +new Date() 等方式。
举个例子,我们可以使用 Date.now() 获取当前时间戳:
var now = Date.now(); console.log(now); // 输出当前时间戳
Object.keys()
Object.keys() 可以用于获取一个对象自身所有的属性名,返回值是一个数组。此外,还有 Object.getOwnPropertyNames() 和 Object.getOwnPropertySymbols() 这两个方法可以获取对象中的所有属性名,包括自身和继承的属性。
举个例子,我们可以使用 Object.keys() 获取一个对象的所有属性名:
var obj = {a: 1, b: 2, c: 3};
var keys = Object.keys(obj);
console.log(keys); // 输出 ['a', 'b', 'c']新增对象和类型
JSON 对象
在 ES5 中,引入了一个新的 JSON 对象,它提供了一组用于解析和序列化 JSON 数据的方法。其中,JSON.parse() 可以将一个 JSON 字符串转换为一个 JavaScript 对象;JSON.stringify() 可以将一个 JavaScript 对象序列化为一个 JSON 字符串。
举个例子,我们可以使用 JSON 对象将下面的 JSON 字符串解析出来:
{"name": "Tom", "age": 22}var jsonStr = '{"name": "Tom", "age": 22}';
var obj = JSON.parse(jsonStr);
console.log(obj.name); // 输出 Tom新的数据类型:nullish
在 ES5 中,还引入了一种新的数据类型 nullish,它用于表示一个值为 null 或 undefined。使用 nullish 类型,可以更加准确地判断一个变量是否为空值。
举个例子,在 ES5 中,使用 || 运算符判断一个变量是否为空值时,有可能会出现错误的情况,比如下面这个例子:
function test(val) {
var a = val || 10;
console.log(a);
}
test(0); // 输出 10
test(""); // 输出 10
test(undefined); // 输出 10,虽然 val 为 undefined 但被视为 false 返回 10在 ES5 中,我们可以使用 nullish 类型的双问号运算符 ?? 解决上述问题,如下所示:
function test(val) {
var a = val ?? 10;
console.log(a);
}
test(0); // 输出 0
test(""); // 输出 ""
test(undefined); // 输出 10ES6(2015 年发布)
ES6 在 ES5 的基础上引入了大量的新语法和新功能。下面将分为以下几个部分详细介绍其新增特性。
声明变量
let 和 const
ES6 引入了两个新的声明变量的关键字:let 和 const。其中,let 用于声明变量,其作用域为块级作用域;const 用于定义常量,一旦赋值便不能修改。
举个例子,我们可以使用 let 声明一个块级作用域的变量:
if (true) {
let a = 10;
}
console.log(a); // 报错,a 未定义我们还可以使用 const 定义一个常量:
const PI = 3.14; PI = 3; // 报错,常量不可修改
字符串
模板字符串
ES6 中新增了一种字符串表示方式:模板字符串,它使用反引号()括起来,并且可以在其中使用 ${}` 语法插入变量或表达式。
举个例子,我们可以使用模板字符串打印出一个 Greetings:
const name = 'Tom';
console.log(`Greetings, ${name}!`);新增方法
ES6 还新增了一些字符串的操作方法,包括 startsWith()、endsWith()、includes()、repeat() 等等。
举个例子,我们可以使用 startsWith() 判断一个字符串是否以给定的字符串开头:
const str = 'hello world';
const res = str.startsWith('hello');
console.log(res); // 输出 true函数
箭头函数
箭头函数是 ES6 中一个很重要的新特性,它是一种更加简短、更加易读的函数写法。箭头函数会自动绑定作用域,同时也没有自己的 this、arguments,使得函数的调用更加直观。
举个例子,我们可以用箭头函数重新写一个 forEach() 循环:
const arr = [1, 2, 3];
arr.forEach((item) => {
console.log(item);
});默认参数值
ES6 引入了默认参数值的概念,这样我们就可以在定义函数时给参数指定一个默认值。为了避免解释模糊,下面给出一个例子:
function func(a, b = 10) {
console.log(a, b);
}
func(1); // 输出 1, 10
func(1, 2); // 输出 1, 2数组
扩展运算符
扩展运算符是 ES6 中一个重要的特性,它可以将一个数组展开成一个序列。
举个例子,我们可以使用扩展运算符将两个数组中的元素拼接起来:
const arr = [1, 2, 3]; const arr2 = [4, 5, 6]; const res = [...arr, ...arr2]; console.log(res); // 输出 [1, 2, 3, 4, 5, 6]
新增方法
ES6 新增了一些数组的操作方法,包括 map()、filter()、find()、findIndex() 等等。
举个例子,我们可以使用 map() 将一个数组中的元素进行处理,返回一个新的数组:
const arr = [1, 2, 3]; const res = arr.map(item => item * 2); console.log(res); // 输出 [2, 4, 6]
对象
对象字面量增强
ES6 引入了一些新语法用于简化对象的创建和操作,其中包括了新的属性访问方式、方法的快速定义、计算属性名等等。
举个例子,我们可以使用新语法创建一个包含方法和计算属性名的对象:
// www.javascriptcn.com code example
const name = 'Tom';
const age = 22;
const obj = {
name,
age,
sayName() {
console.log(this.name);
},
[`hello ${name}`]: 'World'
};
console.log(obj['hello Tom']); // 输出 WorldSymbols
ES6 新增了一个新的基本数据类型 Symbol,它表示独一无二的标识符。Symbol 用于定义类的私有属性以及常量等一些特殊的用途。
举个例子,在工厂模式中,一个类的实例可以通过传入不同的参数来创建不同版本的对象,这种方法是不够优雅的,而使用 Symbol 就可以优雅的解决该问题,如下所示:
// www.javascriptcn.com code example
const color = Symbol('color');
class Ball {
constructor(c) {
this[color] = c;
}
get() {
return this[color];
}
}
const ball1 = new Ball('Red');
const ball2 = new Ball('Green');
console.log(ball1.get()); // 输出 Red
console.log(ball2.get()); // 输出 GreenES7(2016 年发布)
ES7 引入的特性主要是一些提议阶段的语法和 API,包括 Async/Await、Array.prototype.includes、指数运算符等等。
Async / Await
Async / Await 是 ES7 引入的一种异步编程方案,它使得异步代码看起来更加同步化,并且更加易于理解。Async / Await 是建立在 ES6 之上的一种语法,使用 Async / Await 需要配合 Promise 来使用。
举个例子,我们可以使用 Async / Await 来实现一个 HTTP 请求:
async function fetchData() {
const data = await fetch('https://api.github.com');
console.log(await data.json());
}
fetchData();Array.prototype.includes
Array.prototype.includes() 是一种用来查找数组中是否包含某个元素的新方法。它类似于 indexOf(),但是在查找 NaN 等元素时更加准确。
举个例子,我们可以使用 includes() 查找一个数组中是否包含某个元素:
const arr = [1, 2, 3]; const res = arr.includes(2); console.log(res); // 输出 true
指数运算符
ES7 引入了一种新的指数运算符,它使用两个 * 号来表示乘方运算符。
举个例子,我们可以使用指数运算符计算一个数的平方:
const res = 2 ** 2; console.log(res); // 输出 4
ES8(2017 年发布)
ES8 引入的新特性主要是一些提议阶段的语法和 API,包括新增的方法修饰符、Object.values()、Object.entries()、异步迭代器等等。
方法修饰符
ES8 新增了三种方法修饰符:public、private、protected。这些修饰符被用于类和类的成员中,分别用于表示公共方法、私有方法和受保护方法。
举个例子,在一个 Class 中使用这些修饰符:
// www.javascriptcn.com code example
class MyClass {
public() {
console.log('public');
}
#private() {
console.log('private');
}
protected() {
console.log('protected');
}
}Object.values()
Object.values() 方法用于获取一个对象自身的所有属性值组成的一个数组。该方法返回的值顺序与 for…in 循环遍历对象的顺序一致。
举个例子,我们可以使用 Object.values() 获取一个对象所有的属性值:
const obj = {a: 1, b: 2, c: 3};
const res = Object.values(obj);
console.log(res); // 输出 [1, 2, 3]Object.entries()
Object.entries() 方法用于获取一个对象自身的所有属性键值对组成的数组。该方法返回的值包含每个属性的键名和键值。
举个例子,我们可以使用 Object.entries() 获取一个对象的所有属性键值对:
const obj = {a: 1, b: 2, c: 3};
const res = Object.entries(obj);
console.log(res); // 输出 [['a', 1], ['b', 2], ['c', 3]]异步迭代器
异步迭代器是 ES8 中一个非常重要的新特性,它允许我们通过异步的方式迭代某些具有异步特性的数据集合,如文件、数据库等等。异步迭代器类似于普通的迭代器,但是其返回的是一个 Promise 对象,它的值是迭代器下一个值。
举个例子,我们可以使用异步迭代器遍历一个 Async Iterable:
// www.javascriptcn.com code example
async function count() {
let i = 0;
while (i < 3) {
await new Promise(resolve => setTimeout(resolve, 1000));
yield i++;
}
}
async function run() {
for await (const value of count()) {
console.log(value);
}
}
run();小结
随着 JavaScript 标准的不断更新,我们可以通过使用 ES5、ES6、ES7、ES8 等版本来使用更加丰富和强大的语言特性。本文介绍了这些版本新增的一些特性,希望能够帮助读者更加深入地了解 JavaScript 语言,并且掌握其最新的开发动态。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67cfef37e46428fe9ec42b6e