Javascript moderne: tout ce que vous avez manqué au cours des 10 dernières années

JavaScript a parcouru un long chemin depuis que je l'ai connu sous le nom de lettre «D» en DHTML. Pour tous ceux comme moi qui ne souhaitaient pas utiliser la dernière syntaxe pouvant nécessiter des polyfills ou un transpilateur, j'ai écrit cette feuille de triche pour vous familiariser avec tous les avantages largement pris en charge dans les navigateurs modernes.



Contenu



  • Fonctions de tableau
  • const / let
  • Coalescence nulle ?? et Chaînage optionnel? .. opérateurs
  • Asynchrone / Attendre
  • Fonctions fléchées () => {}
  • pour ... de
  • pour attendre ... de
  • Des classes
  • se mettre
  • paramètres par défaut de la fonction
  • function named parameters
  • function rest… parameter
  • Destructuring
  • Shorthand functions aka Methods
  • Promise.all
  • Template literals
  • Proxy
  • Module import/export


( , , )





Array functions



Découvrez toutes ces nouvelles fonctions de tableau natif. Plus besoin de soulignement ou de lodash.



Array.every ()

Array.filter ()

Array.find ()

Array.findIndex ()

Array.forEach ()

Array.from ()

Array.includes ()

Array.isArray ()

Array.lastIndexOf ()

Array.map ()

Array.reduce ()

Array.reduceRight ()

Array.some ()



Array docs



const / let



Ces nouveaux mots clés déclarent des variables dans la portée de bloc (par opposition à la portée globale ou fonctionnelle). L'utilisation const



implique que la valeur que la valeur ne doit pas changer, mais let



donne cette opportunité.



Laissez la documentation



?? et?.



??



vérifie si une valeur est nulle ou indéfinie. Plus besoin de l'utiliser !!



.



?.



vérifie si une valeur est vraie avant d'appeler la propriété ou la fonction suivante. Extrêmement utile lorsqu'il s'agit d'accessoires supplémentaires.



Documentation de chaînage en option



let a, b=1
let result = a ?? b
print(result)

result = (a !== null && a !== undefined) ? a : b;
print(result)
      
print({x:1}?.a?.b ?? "not found")
      
      
      







Asynchrone / Attendre



Les mots-clés async / await sont là pour vous sauver de l'enfer des rappels. Utilisez await



pour faire ressembler un appel asynchrone à un appel synchrone, c'est-à-dire l'exécution await fetchUserName()



ne passera pas à la ligne suivante tant que fetchUserName () ne sera pas terminé. Veuillez noter que pour l'utiliser await



, vous devez exécuter une fonction déclarée asynchrone, c'est-à-dire async function fn () {await fetchUserName ()}.







Documents Async / Await.



function fetchUserName() {
  return new Promise(resolve => setTimeout(resolve, 500))
}
      
async function withAsync() {
  print("withAsync: fetching...")
  await fetchUserName()
  print("withAsync: done")
}
await withAsync()
      
function withoutAsync() {
  print("withoutAsync: fetching...")
  fetchUserName().then(()=>print("withoutAsync done"))
}
withoutAsync()
    
      
      







Fonctions fléchées () => {}



Ce sont des fonctions liées au contexte actuel. Il existe trois types principaux que vous verrez dans la nature:

un argument, une ligne, plusieurs lignes.



Un formulaire à un seul argument ne nécessite pas de parenthèses et un formulaire à une seule ligne ne nécessite pas d'opérateur return



; retour inconditionnel.



1 const fn = a => a*2
      
      







Un argument. Une ligne.



Un formulaire multiligne nécessite une instruction return



si la fonction a l'intention de renvoyer quelque chose. Les arguments multiples nécessitent des parenthèses.



const fn = (a,b) => {
  console.log(a,b)
  return a*b
}
      
      







Plusieurs arguments, plusieurs lignes.



Documentation sur la fonction de flèche



pour ... de



Utilisé pour parcourir un itérateur. De même for...in



, sauf que vous n'avez pas besoin de vérifier hasOwnProperty



. Vous ne pouvez pas utiliser cette syntaxe de boucle sur un objet directement car l'objet n'a pas d'itérateur. Utilisez plutôt Object.entries ({})



pour obtenir une itération.



pour ... de documents



const x = {a: 1, b: 2}
for (const [key, value] of Object.entries(x)) {
  print(`${key}=${value}`)
}
      
      







pour attendre ... de



L'itération asynchrone a été introduite en 2018. De plus Promise.all



, il peut être utilisé pour synchroniser de nombreuses tâches asynchrones. L'exemple ci-dessous montre 3 tâches s'exécutant de manière asynchrone. La boucle traite un résultat à la fois, dans l'ordre; dans ce cas, les tâches les plus rapides à accomplir ne sont évidentes qu'à la fin de l'itération.



pour attendre ... de docs



const delay = (n) => {
  return new Promise((resolve) => {
    setTimeout(()=>{
      print("resolve "+n)
      resolve(n)
    }, n)
  })
}

const delays = [
  delay(150),
  delay(50),
  delay(25)
]

for await (const ret of delays) {
  print("for loop await "+ret)
}
      
      







Des classes



En 2015, ES6 a porté les classes vers Javascript. Les classes Javascript sont comme des classes d'autres langages que vous connaissez et aimez. Héritage, méthodes de classe, getters et setters, propriétés, etc.



Documentation de classe



class A {
  constructor(name) {
    this.name = name
  }
  myProp = "myProp"
  static foo() {
    print("Static method says foo")
  }
}
class B extends A {
  constructor(name, age) {
    super(name)
    this.age = age
  }
  toString() {
    return `${this.name} ${this.age}`
  }
}
A.foo()
const b = new B("Catch", 22)
print(b)
print(b.myProp)
      
      







se mettre



Get et set sont des fonctions appelées propriétés, par exemple person.age = 16; person.age> 18



. Ceci est très pratique lorsque vous avez besoin d'une propriété dynamique ou calculée. Et ils peuvent être utilisés à la fois avec des classes et des objets normaux.



get / set documentation



Classes avec getters et setters

class A {
  constructor() {
    this._firstName = "Jane"
    this._lastName = "Smith"
  }
  get fullName() {
    return `${this._firstName} ${this._lastName}`
  }
  set firstName(v) {
    this._firstName = v
  }
}
const a = new A()
print(a.fullName)
a.firstName = "John"
print(a.fullName)
      
      







Objets avec getters et setters

const x = {
  get now() { return new Date() }
}
print(x.now)
      
      







paramètres par défaut de la fonction



Hourra! Vous pouvez maintenant spécifier les paramètres par défaut dans votre définition de fonction. Fonctionne comme vous vous en doutez.



Documentation sur les paramètres par défaut



function greet(msg="Hello world") {
  print(msg)
}
greet()
greet("hi")
      
      







fonction nommée paramètres



Grâce à la magie de la déstructuration des objets, les fonctions peuvent désormais avoir des paramètres nommés.



Documentation sur les paramètres nommés



function greet({name = "Jane", age = 42} = {}){
  print(name + " " +age)
}
greet()
greet({name: "John", age: 21})
      
      







fonction reste ... paramètre



Le paramètre reset permet à la fonction d'accepter un nombre arbitraire d'arguments sous forme de tableau. Il est recommandé de l'utiliser à la place arguments



.



Documentation sur les paramètres de repos



function greet(msg1, ...msgs) {
  print(msg1)
  msgs.forEach(s => print(s))
}
greet("hi", "hello", "world")
      
      







Object.assign et opérateur de diffusion



Object.assign(target, source)



combine deux objets ou plus en un seul. Il modifie la cible sur place, donc si vous préférez créer un nouvel objet, passez un littéral d'objet vide comme premier argument.



Alternativement, vous pouvez utiliser l'opérateur de diffusion ...



pour combiner plusieurs objets: {... obj1, ... obj2}



bien que gardez à l'esprit que spread



cela n'appellera pas de setters sur un objet, donc pour être le plus portable, considérez Object.assign



. L'opérateur Spread peut également être utilisé avec des tableaux, comme indiqué dans le dernier exemple de code.



Diffuser des documents sur la syntaxe



const source = {x: 1, y: 4}
const target = Object.assign({}, source)
print(JSON.stringify(target))

const spread = {a: 1, b: 2, ...source}
print(JSON.stringify(spread))

const ary1 = [1]
const ary = [...ary1, [2,3]]
print(ary)
      
      
      







Destructuration



La destruction vous permet de récupérer des valeurs d'objets et de tableaux à l'aide de modèles. C'est un sujet complexe avec de nombreuses applications ... trop pour que je puisse en énumérer, mais j'ai montré certaines des utilisations les plus courantes auxquelles je peux penser.



Docs de destruction et documents MDN



function f() {
  return [1, 2];
}
let [a, b] = f()
print("a="+a + " b=" + b)

const obj = {state: {id: 1, is_verified: false}}
const {id, is_verified: verified} = obj.state
print("id = " + id)
print("verified = " + verified)

for (const [key, value] of Object.entries({a: 1, b: 2, c: 3})) {
  print(key + " is " + value);
}
      
      
      







Fonctions abrégées aka Méthodes



Les fonctions déclarées pour les objets peuvent utiliser le nouveau style abrégé, qui n'a pas le mot-clé function.



Les deux fonctions (fn1, fn2) sont équivalentes dans l'exemple ci-dessous.



Guide de méthode



const x = {
  type: "x",
  shorthand() {
    print("shorthand "+this.type)
  },
  long: function() {
    print("long "+this.type)
  }
}
x.shorthand()
x.long()

      
      







Promise.all



J'ai pour la plupart ignoré les promesses car async / await est préférable, mais parfois vous devez synchroniser plusieurs appels asynchrones et Promise.all est le moyen le plus simple de le faire.



Documentation Promise.all



const delay = (n) => {
  return new Promise((resolve) => {
    setTimeout(()=> resolve(n), n)
  })
}
async function main() {
  const delays = [100, 200, 300].map(n => delay(n))
  print("waiting…")
  const res = await Promise.all(delays)
  print("done. result is " + res)
}
main()
      
      
      







Littéraux de modèle



Cette nouvelle syntaxe, également connue sous le nom de chaînes de modèle, fournit une interpolation de chaîne simple et des chaînes multilignes.



Documents littéraux de modèle



let x = `multi
      line
string`
print(x)

x = `1+1=${1+1}`
print(x)
      
      







Procuration



Un proxy vous permet d'intercepter les appels get / set sur un autre objet. Cela peut être utile pour suivre les modifications de propriété, mettre à jour le DOM ultérieurement ou créer des API innovantes comme le proxy www ci-dessous. Documents proxy



image







let _nums = [1,2,3]
let nums = new Proxy(_nums, {
  set(target, key, value) {
    target[key] = value
    print("set called with " + key + "=" + value)
    print("update DOM")
    return true
  }
})
nums.push(4)
print("nums: " + nums)
print("_nums: " + _nums)
      
      







Importation / exportation de modules



Les modules vous permettent de créer un espace de noms pour votre code et de décomposer les fonctionnalités en fichiers plus petits. Dans l'exemple ci-dessous, nous avons un module nommé greet.js qui est inclus dans index.html. Veuillez noter que le chargement du module est toujours différé, il ne bloque donc pas le rendu HTML. Il existe de nombreuses façons d'importer / exporter des fonctionnalités à partir de fichiers js, lisez la documentation d'exportation pour plus de détails .



Importer des documents



function greet(msg) {
  console.log("greet:", msg)
}
export default greet
      
      







Un fichier nommé "greet.js" dans le répertoire "/ js".



<script type="module">
  import greet from "/js/greet.js"
  greet("hi")
</script>
      
      







index.html



Lire la suite



Donc, je n'ai pas parlé de tout ce qui a changé au cours de la dernière décennie, mais seulement de ce que je trouve le plus utile. Consultez ces autres sujets.



Les références





Guides




All Articles