Vous êtes peut-être nouveau dans JavaScript ou vous ne l'avez peut-être utilisé qu'occasionnellement. Quoi qu’il en soit, JavaScript a beaucoup changé et certaines fonctionnalités valent la peine d’être utilisées. Cet article présente certaines fonctionnalités qu'à mon avis, un développeur JavaScript sérieux utilisera à un moment donné chaque jour.
Références
Les deux sites suivants sur ES6+ sont mes favoris :
-
Fonctionnalités ES6
MDN
Opérateur d'expansion
Comme son nom l'indique, l'opérateur de propagation (...) utilisé avant qu'un objet ou un tableau ne se développe. une liste. Démontrez-le :
let firstHalf = [ 'one', 'two']; let secondHalf = ['three', 'four', ...firstHalf];
Cette méthode d'écriture est-elle suffisamment élégante et concise ? Si l'opérateur d'expansion n'est pas utilisé, il faut écrire ainsi :
let firstHalf = [ 'one', 'two']; let secondHalf = ['three', 'four']; for(var i=0, i <firstHalf.length; i++ ) { secondHalf.push(firstHalf[i]); }
L'opérateur d'expansion convient également pour fusionner les propriétés d'objets :
const hero = { name: 'Xena - Warrior Princess', realName: 'Lucy Lawless' } const heroWithSword = { ...hero, weapon: 'sword' }
Si l'opérateur d'expansion n'est pas utilisé, il faut parcourir les propriétés de l'objet :
let keys = Object.keys(hero); let obj = {}; for(var i=0; i< keys.length; i++) { obj[keys[i]] = keys[props[i]]; }
Paramètres restants
Les paramètres restants incluent les paramètres restants dans la séquence. La particularité de JavaScript est que le nombre de paramètres est très flexible. Il existe généralement une variable arguments collectant les arguments. Regardons un exemple :
function add(first, second, ...remaining) { return first + second; }
Le morceau de code ci-dessus ajoute uniquement le premier et le deuxième, c'est-à-dire qu'appeler add(1, 2) et add(1, 2, 3, 4) obtiendra le même résultat . Corrigeons le problème :
function add(first, second, ...remaining) { return first + second + remaining.reduce((acc, curr) => acc + curr, 0); }
Comme mentionné précédemment, ...remaining collecte les paramètres restants et nous donne un nom pour ces paramètres, indiquant clairement que nous avons l'intention de gérer les paramètres restants. Je me souviens qu'ES5 a déjà des arguments au plus tard, mais peu de gens le savent.
Interpolation de chaînes
Avez-vous déjà vu une telle déclaration ?
class Product { constructor(name, description, price) { this.name = name; this.description = description; this.price = price; } getDescription() { return " Full description \n" + " name: " + this.name + " description: " + this.description } }
Bien sûr, je fais référence à cette longue instruction multiligne illisible dans la méthode getDescription(). Un phénomène similaire existe dans la plupart des langages de programmation. Plusieurs langages proposent l'interpolation de chaînes, et heureusement, JavaScript en fait partie. Réécrivons la méthode getDescription() : l'interpolation
getDescription() { return `Full description \n: name: ${this.name} description ${this.description} `; }
${} peut être utilisée dans une paire de chaînes `-wrappées. Cela a l'air beaucoup plus confortable maintenant.
L'attribut d'abréviation
doit être écrit comme ceci dans ES5 :
function createCoord(x, y) { return { x: x, y: y } }
Dans ES6, l'attribut d'abréviation peut être utilisé à l'avenir :
function createCoord(x, y) { return { x, y } }
Est-ce que ça a l'air plus rafraîchissant ?
Attribut de méthode
L'attribut de méthode est un attribut défini dans l'objet qui pointe vers une méthode. Considérons le morceau de code ES5 suivant comme exemple :
const math = { add: function(a,b) { return a + b; }, sub: function(a,b) { return a - b; }, multiply: function(a,b) { return a * b; } }
ES6 n'aura besoin d'écrire ceci qu'à l'avenir :
const math = { add(a,b) { return a + b; }, sub(a,b) { return a - b; }, multiply(a,b) { return a * b; } }
Assignation de déstructuration
L'affectation de déstructuration est bonne pour le santé mentale du développeur lui-même.
Considérez le code suivant :
function handle(req, res) { const name = req.body.name; const description = req.body.description; const url = req.url; log('url endpoint', url); // 大量代码逻辑 dbService.createPerson(name, description) }
Peu importe d'un point de vue, le code ci-dessus n'est pas parfait, mais il reflète un scénario d'application dans lequel nous voulons visualiser des objets de différents niveaux. données. Vous vous demandez peut-être quel est le problème ici ? Eh bien, je peux m'épargner quelques frappes en ne déclarant pas autant de variables.
function handle(req, res) { const { body: { name, description }, url } = req; log('url endpoint', url); // 大量代码逻辑 dbService.createPerson(name, description)
Regardez, notre code ci-dessus condense trois lignes en une seule.
La mission de déstructuration ne se limite pas aux objets. Cela fonctionne également bien avec les tableaux. Considérons le code suivant :
const array = [1,2,3,4,5,6]; const a = array[0]; const c = array[2];
Le code ci-dessus peut être réécrit de manière plus élégante :
const array = [1,2,3,4,5,6]; const [a, ,c, ...remaining] = arr; // remaining = [4,5,6]
Nous pouvons utiliser la correspondance de modèles ci-dessus pour décomposer les valeurs du tableau. Nous utilisons , , pour ignorer certaines valeurs. Les paramètres restants mentionnés ci-dessus peuvent également être utilisés ici. Ici, nous capturons les membres restants du tableau via les paramètres restants.
L'affectation de déstructuration peut également être utilisée pour les fonctions et les paramètres. Lorsqu'une fonction a plus de 2 ou 3 paramètres, il est de facto standard en JavaScript d'utiliser un objet pour collecter tous les paramètres. Par exemple, la fonction suivante :
function doSomething(config) { if(config.a) { ... } if(config.b) { ... } if(config.c) { ... } }
a une meilleure façon d'écrire :
function doSomething({ a, b, c }) { if(a) { ... } if(b) { ... } if(c) { ... } }
Méthode tableau
ES6 introduit de nombreuses méthodes de tableau utiles, telles que :
- find(), trouve les membres dans la liste, renvoie null pour indiquer introuvable
- findIndex(), trouve l'index du membre de la liste,
- some(), vérifie si une assertion est au moins vraie sur un membre de la liste
- inclut, si la liste contient un élément
Le code suivant vous aidera à comprendre leur utilisation :
const array = [{ id: 1, checked: true }, { id: 2 }]; arr.find(item => item.id === 2) // { id: 2 } arr.findIndex(item => item.id === 2) // 1 arr.some(item => item.checked) // true const numberArray = [1,2,3,4]; numberArray.includes(2) // true
Promesses + Async/Await
Si vous êtes dans ce cercle depuis quelques années, vous vous souvenez peut-être qu'il fut un temps où nous n'avions que des rappels, comme ceci :
function doSomething(cb) { setTimeout(() => { cb('done') }, 3000) } doSomething((arg) => { console.log('done here', arg); })
Nous avons utilisé des rappels car certaines opérations sont asynchrones et prennent du temps. Ensuite, nous avons eu la bibliothèque de promesses et les gens ont commencé à l'utiliser. Ensuite, JavaScript a progressivement ajouté la prise en charge native des promesses.
function doSomething() { return new Promise((resolve, reject) => { setTimeout(() => { resolve('done') }, 3000) }) } doSomething().then(arg => { console.log('done here', arg); })
On peut même l'appeler ainsi pour enchaîner les promesses :
getUser() .then(getOrderByUser) .then(getOrderItemsByOrder) .then(orderItems => { // 处理排序后的成员 })
后来生活更加美好,我们有了 async/await, 上面一段代码可以这样写:
async function getItems() { try { const user = await getUser(); const order = await getOrderByUser(user); const items = await getOrderItemsByOrder(order); return items; } catch(err) { // 在这里处理错误,建议返回某个值或者重新抛出错误 } } getItems().then(items => { // 处理排序后的成员 })
模块
差不多任何编程语言都支持模块这一概念,也就是将代码分为多个文件,每个文件是一个自我包含的单元(模块)。 考虑下面的代码:
// math.js export function add(a,b) { return a + b; } export function sub(a,b) { return a - b; } export default mult(a,b) => a * b; // main.js import mult, { add, sub } from './math'; mult(2, 4) // 8 add(1,1) // 2 sub(1,2) // -1
我们在上面用 export 关键字注明了 add 和 sub 这两个结构对任何引入该模块的模块都公开可见。 export default 关键字则注明仅仅 import 模块时得到的结构。 在 main.js 中,我们将导入的 default 命名为 mult,同时指明我们引入 add() 和 sub() 这两个方法。
箭头函数和字典作用域 this
我在这篇文章中很多地方都用到了箭头函数,它不过是另一种函数表示法。 过去我们只能这么声明函数:
function printArray(arr) { // 具体操作 }
现在我们也可以这么写:
const printArray = (arr) => { // 具体操作 }
我们也可以将函数声明写到一行里:
const add = (a,b) => a + b
上面的代码表明我们进行操作并返回结果。 我们也可以采用下面的语法返回一个对象:
const create = (a,b) = > ({ x: a, y: b })
过去会碰到搞不清 this 是什么的问题。 考虑下面的代码:
let array = [1,2,3]; function sum() { this.total = 0; arr.forEach(function(item) { this.total+= item; // 糟糕,`this` 是内层函数的 `this` }) return total; }
上面代码中的 this 指向 forEach 内部函数的 this,这可不是我们想要的。 过去我们通过以下方式解决这个问题:
function sum() { this.total = 0; var self = this; arr.forEach(function(item) { self.total+= item; // 这里我们使用 `self`,它能解决问题,但是感觉有点别扭 }) return total; }
箭头函数可以解决问题,再也不用 self 了,现在代码看起来是这样的:
function sum() { this.total = 0; arr.forEach((item) => { this.total+= item; // 一切安好,`this` 指向外层函数 }) return total; }
大胜!
结语
我还可以讲讲更多 ES6 方面的内容,不过这篇文章中我只打算介绍我最偏爱的特性。 我觉得你应该从今天开始使用这些特性。
【相关推荐:javascript高级教程】