最新 Javascript 中最有用的特性(自 ES6 以来)

521 阅读6分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

英文原文链接:The Most Useful Features in the Latest Javascript (Since ES6)

2015 年 6 月,在中断了六年之后,Javascript 进行了一次重大更新,带来了许多新特性。从那时起,我们每年都会推出一个新版本,包含一系列新特性,旨在帮助开发人员提高工作效率。为了帮助您跟踪 Javascript 版本的进展情况,我将按版本分组列出最有用的特性,并添加一些代码示例,以便更好地概述。

ES6 (ECMAScript 2015)

箭头函数 (=>)

箭头函数是函数语法(=>)的简写。它为开发人员带来了两个主要的便利。首先,箭头函数帮助我们避免使用 .bind() 或其他用于正确地应用 this 的方法,因为箭头函与它们周围共享了相同的词法 this。使用箭头函数的另一个好处是,我们的代码看起来好多了,它不像使用常规函数那么冗长。

// traditional function expression
var numbers = [2, 6, 40];
var twiceNum = numbers.map(function (number) { return number * 2 })

// arrow functional
var numbers = [2, 6, 40];
var twiceNum = numbers.map((number) => number * 2);
// lexical this
var greenBtn = document.getElementById(‘greenBtn’);
greenButton.addEventListener(‘click’, function () {
    this.style.backgroundColor = “red”; // no more binding
})

对于面向对象编程的乐趣,类可能是一个非常有用的特性。它们使基于类模式编写代码变得超级容易。类支持原型继承、构造函数、 super 调用以及实例和静态方法。让我们看看现在创建类有多容易:

// Class
class Person {
    constructor(firstName, lastName, age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
    sayHi() {
        returnHi, my name is ${ firstName }.Nice to meet you.’;
    }
}

模板字符串

在上面的例子中,你可能意识到我没有使用加号将变量添加到字符串中。ES6 实现了一个非常有用的特性,叫做模板字符串。它允许我们在不中止字符串的情况下实现变量。把变量放到花括号中,在 is 前面加上 $ 符号就足够了。将字符串前后加引号也是很重要的。在构造 API 请求时,它可能非常有用。让我们看一看代码:

var name = ‘Peter’, city = ‘London’;
// Before ES6
var greeting = "Hello, my name is " + name + ". I am from " + city + ".";
// After ES6 
var greeting = ‘Hello, my name is ${name}. I’m from ${city}.‘

Let 和 Const

ES6 实现了两个新的关键字: const 和 let 。它们都用于声明变量。Let 的工作原理与 var 非常相似,但变量具有块作用域,所以它只在声明的代码块中可用。const 用于声明常量。它的工作方式类似于 let ,但在声明 const 时需要赋值。让我们看一看代码示例:

// Let — variable is available only in the block of code
function calculate(x) {
    var y = 0;
    if (x > 10) {
        // let y is only available in this block of code
        let y = 30;
        return y;
    }
    return y;
}

Promises

ECMAScript 2015 的创建者还为我们提供了标准化的 Promise 实现,这非常有用,而我们现在经常使用异步编程。我们再也不用担心回调"地狱"了。Promise 总是处于以下三种状态之一: 等待、完成或拒绝。如果 Promise 被解析,您还可以使用 .then() 方法进行响应,或者使用 .catch() 方法检查它为什么被拒绝。让我们看一看代码:

const checkResult = () => new Promise(resolve, reject) => {
    setTimeout(resolve, 500)
}
checkResult()
    .then((result) => { console.log(result); })
    .catch((error) => { console.log(error); })

ES7 (ECMAScript 2016)

Array.prototype.includes

在 ES7 中出现了一个用于数组的新方法。.includes() 方法使检查数组中是否有特定值变得更容易。以前开发人员使用 indexOf ,必须创建一个额外的函数来检查,现在我们可以使用 .include() ,如果数组中有特定的元素,它将返回 true ,如果没有,则返回 false 。让我们看一个代码示例:

var fruits = ['banana', 'apple', 'grape', 'nut', 'orange'];
var favoriteFruit = 'banana';
// Before ES7
function isFruit(fruit) {
    if (fruits.indexOf(fruit) !== -1) {
        return true;
    } else {
        return false;
    }
}
isFruit(favoriteFruit); // returns true
// After ES7
fruits.includes(favoriteFruit); // returns true

取幂运算

对于致力于更高级的数学运算、3D、VR 或数据可视化的开发者来说,这是最重要的。以前,这可以通过循环、Math.pow() 或递归函数来完成,现在方法简单多了。让我们看一些代码:

// Before ES7 (loop case) 
function calculate(num, exponent) {
    var res = 1;
    for (var i = 0; i < exponent; i++) {
        res *= num;
    }
    return res;
}
// After ES7
const calculate = (num, exponent) => num ** exponent;

ES8 (ECMAScript 2017)

Object.values() 和 Object.entries()

在 ECMAScript2017 中实现的 object .values() 方法允许我们接受对象的所有值,并将它们作为数组返回。ES8 中 Object 的另一个有用特性是 Object.entries() 方法。它允许我们获取所有的条目,并将它们显示为数组的数组。让我们看一些代码:

var person = {
    name: ‘Jenny’,
    age: 24,
    country: ‘UK’,
    city: ‘London’,
}
// Object.values()
var arrJenny = Object.values(person); // returns [‘Jenny’, 24, ‘UK’, ‘London’];
// Object.entries()
var arrJennyEntries = Object.entries(person); // returns [[‘name’, ‘Jenny’], [‘age’, 24], [‘country’, ‘UK’], [‘city’, ‘London’]];

String.prototype.padEnd() 和 String.prototype.padStart()

在 ES8 中也有一些新的字符串。当您的字符串没有足够的长度时,您可以使用其中一种新方法来添加一些字符,直到它达到所需的长度。padEnd() 将在字符串的末尾添加选定的字符(默认为空格),padStart() 表示在字符串的开头添加。让我们在例子中看看它是如何工作的:

var string = ‘Alice’;
// padStart() — we assume our string needs to have 10 characters 
string.padStart(10, ‘o’); // returns ‘oooooAlice’
// padEnd() 
string.padEnd(10, ‘o’); // returns ‘Aliceooooo’;

异步函数 (async/await)

在 ES8 中,开发者为异步编程提供了另一种替代回调和 Promise 的方法,即 async/await 函数。Async 函数定义了一个异步函数,并返回一个将被解析或拒绝的 Promise 。还有 .await() 操作符在异步函数中使用,它等待 Promise 。异步函数为我们提供了更友好的语法。让我们看看一些代码

function delayResult() {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(‘Done’);
        }, 5000)
    })
}
async function getResult() {
    var result = await delayResult();
    return result;
}
getResult();

ES9 (ECMAScript 2018)

异步迭代

ES9 的创建者添加了异步迭代,这意味着你可以使用 await 来声明异步循环。但是它只能在数据来自同步源的情况下使用,所以我们不能异步迭代来自 https fetch 的数据。让我们看一下代码示例:

for await (let book of books) { 
     console.log(book) 
};

rest 操作符

ECMAScript2019 还为 rest 操作符带来了新的行为。现在,它可以将对象字面量中没有提到的剩下的对象 键值对 复制到操作数中。rest 操作符应该在末尾使用; 否则,将导致错误。同样,也可以在函数中使用它并获取所需的属性。让我们看一个例子来更好地理解它:

const fruits = { orange: 1, apple: 10, banana: 4, } 
const { orange, …rest } = fruits; 
console.log(rest); // { apple: 10, banana: 4 };
// in the function
function getFruits(apple, …rest) { 
     return rest.banana;
}

Promise.prototype.finally

ES9 附带的另一个有用的特性是 .finally() ,它是 Promise 的另一个回调函数,无论调用 .then() 还是 .catch() ,它都会被执行。如果在 Promise 之后你还需要采取一些行动,不管它是否成功,这可能是有用的。让我们看一看代码:

const checkResult = () => new Promise(resolve, reject) => { setTimeout(resolve, 500) }
checkResult()
    .then((result) => { console.log(result); })
    .catch((error) => { console.log(error); })
    .finally(() => { console.log(‘Promise finished!’) })

总结

我们浏览了自 2015 年 ES6 以来最有用的(不是所有的) Javascript 更新。有很多变化你可能直到今天才知道。记住,使用它来更新你的编程知识,使你的代码更聪明、更短、更清晰是非常重要的。