? Le guide complet est maintenant disponible sur Amazon

let , const et BLOCK SCOPING let vous permet de créer des déclarations liées à n'importe quel bloc, appelé blocage du bloc. Au lieu d'utiliser var , qui fournit la portée de la fonction, il est recommandé d'utiliser des variables dans les parasites de blocs ( let ou const ) dans ES6.
var a = 2 ;
{
let a = 3 ;
console . log ( a ) ; // 3
let a = 5 ; // TypeError: Identifier 'a' has already been declared
}
console . log ( a ) ; // 2 Une autre forme de déclaration de blocage est la const , qui crée des constantes. Dans ES6, un const représente une référence constante à une valeur. En d'autres termes, le contenu de Object et du Array peut changer, seul la réaffectation de la variable est empêchée. Voici un exemple simple:
{
const b = 5 ;
b = 10 ; // TypeError: Assignment to constant variable
const arr = [ 5 , 6 ] ;
arr . push ( 7 ) ;
console . log ( arr ) ; // [5,6,7]
arr = 10 ; // TypeError: Assignment to constant variable
arr [ 0 ] = 3 ; // value is mutable
console . log ( arr ) ; // [3,6,7]
}Quelques choses à garder à l'esprit:
let et const varient de la levée traditionnelle des variables et des fonctions. let et const et const sont hissés, mais ne peuvent pas être accessibles avant leur déclaration, en raison de la zone morte temporellelet et const sont de portée au bloc d'encluse le plus proche.const PI = 3.14 )const doit être défini avec sa déclaration.const Over let , sauf si vous prévoyez de réaffecter la variable. Les fonctions de flèche sont une notation à main courte pour les fonctions d'écriture dans ES6. La définition de la fonction de flèche se compose d'une liste de paramètres ( ... ) , suivie du marqueur => et d'un corps de fonction. Pour les fonctions à argument unique, les parenthèses peuvent être omises.
// Classical Function Expression
function addition ( a , b ) {
return a + b ;
} ;
// Implementation with arrow function
const addition = ( a , b ) => a + b ;
// With single argument, no parentheses required
const add5 = a => 5 + a ; Notez que dans l'exemple ci-dessus, la fonction de flèche addition est implémentée avec "corps concis" qui n'a pas besoin d'une instruction de retour explicite. Remarque le { } omis après le => .
Voici un exemple avec le «corps de bloc» habituel. Y compris les emballages de l'agitation bouclés.
const arr = [ 'apple' , 'banana' , 'orange' ] ;
const breakfast = arr . map ( fruit => {
return fruit + 's' ;
} ) ;
console . log ( breakfast ) ; // ['apples', 'bananas', 'oranges']Voir! Il y a plus ...
Les fonctions de flèche ne se font pas seulement le code. Ils sont étroitement liés à this comportement de liaison.
Le comportement des fonctions de flèche avec this mot-clé varie de celle des fonctions normales. Chaque fonction de JavaScript définit son propre this , mais les fonctions de flèche capturent this valeur du contexte d'enfermement le plus proche. Consultez le code suivant:
function Person ( ) {
// The Person() constructor defines `this` as an instance of itself.
this . age = 0 ;
setInterval ( function growUp ( ) {
// In non-strict mode, the growUp() function defines `this`
// as the global object, which is different from the `this`
// defined by the Person() constructor.
this . age ++ ;
} , 1000 ) ;
}
var p = new Person ( ) ; Dans ECMAScript 3/5, ce problème a été résolu en attribuant la valeur en this à une variable qui pourrait être fermée.
function Person ( ) {
const self = this ;
self . age = 0 ;
setInterval ( function growUp ( ) {
// The callback refers to the `self` variable of which
// the value is the expected object.
self . age ++ ;
} , 1000 ) ;
}Comme mentionné ci-dessus, les fonctions de flèche capturent cette valeur du contexte d'enfermement le plus proche, de sorte que le code suivant fonctionne comme prévu, même avec des fonctions flées imbriquées.
function Person ( ) {
this . age = 0 ;
setInterval ( ( ) => {
setTimeout ( ( ) => {
this . age ++ ; // `this` properly refers to the person object
} , 1000 ) ;
} , 1000 ) ;
}
let p = new Person ( ) ;En savoir plus sur «Lexical This» dans les fonctions de flèche ici
ES6 vous permet de définir les paramètres par défaut dans les définitions de fonction. Voici une illustration simple.
const getFinalPrice = ( price , tax = 0.7 ) => price + price * tax ;
getFinalPrice ( 500 ) ; // 850 ... L'opérateur est appelé opérateur de propagation ou de repos, selon comment et où il est utilisé.
Lorsqu'il est utilisé avec n'importe quel itérable, il agit de le "répandre" dans des éléments individuels:
const makeToast = ( breadType , topping1 , topping2 ) => {
return `I had ${ breadType } toast with ${ topping1 } and ${ topping2 } ` ;
} ; const ingredients = [ 'wheat' , 'butter' , 'jam' ] ;
makeToast ( ... ingredients ) ;
// "I had wheat toast with butter and jam"
makeToast ( ... [ 'sourdough' , 'avocado' , 'kale' ] ) ;
// "I had sourdough toast with avocado and kale"La propagation est également idéale pour façonner un nouvel objet à partir d'autres objets:
const defaults = { avatar : 'placeholder.jpg' , active : false }
const userData = { username : 'foo' , avatar : 'bar.jpg' }
console . log ( { created : '2017-12-31' , ... defaults , ... userData } )
// {created: "2017-12-31", avatar: "bar.jpg", active: false, username: "foo"}De nouveaux tableaux peuvent également être façonnés de manière expressive:
const arr1 = [ 1 , 2 , 3 ] ;
const arr2 = [ 7 , 8 , 9 ] ;
console . log ( [ ... arr1 , 4 , 5 , 6 , ... arr2 ] ) // [1, 2, 3, 4, 5, 6, 7, 8, 9] L'autre utilisation commune de ... rassemble tous les arguments dans un tableau. Ceci est appelé opérateur "REST".
function foo ( ... args ) {
console . log ( args ) ;
}
foo ( 1 , 2 , 3 , 4 , 5 ) ; // [1, 2, 3, 4, 5]ES6 permet de déclarer les littéraux d'objets en fournissant une syntaxe raccourci pour initialiser les propriétés à partir de variables et définir les méthodes de fonction. Il permet également la possibilité d'avoir calculé les clés de propriété dans une définition littérale d'objet.
function getCar ( make , model , value ) {
return {
// with property value shorthand
// syntax, you can omit the property
// value if key matches variable
// name
make , // same as make: make
model , // same as model: model
value , // same as value: value
// computed values now work with
// object literals
[ 'make' + make ] : true ,
// Method definition shorthand syntax
// omits `function` keyword & colon
depreciate ( ) {
this . value -= 2500 ;
}
} ;
}
let car = getCar ( 'Kia' , 'Sorento' , 40000 ) ;
console . log ( car ) ;
// {
// make: 'Kia',
// model:'Sorento',
// value: 40000,
// makeKia: true,
// depreciate: function()
// } ES6 a un nouveau soutien pour les littéraux octaux et binaires. La tristesse d'un nombre avec 0o ou 0O la convertirait en valeur octale. Jetez un œil au code suivant:
let oValue = 0o10 ;
console . log ( oValue ) ; // 8
let bValue = 0b10 ; // 0b or 0B for binary
console . log ( bValue ) ; // 2La destructuration aide à éviter la nécessité de variables temporaires lorsqu'elle traite des objets et des tableaux.
function foo ( ) {
return [ 1 , 2 , 3 ] ;
}
let arr = foo ( ) ; // [1,2,3]
let [ a , b , c ] = foo ( ) ;
console . log ( a , b , c ) ; // 1 2 3 function getCar ( ) {
return {
make : 'Tesla' ,
model : 'g95' ,
metadata : {
vin : '123abc' ,
miles : '12000'
}
} ;
}
const { make , model } = getCar ( ) ;
console . log ( make , model ) ; // Tesla g95
const { make , metadata : { miles } } = getCar ( ) ;
console . log ( make , miles ) ; // Tesla 12000
ES6 permet d'utiliser la méthode super dans des objets (sans classe) avec des prototypes. Voici un exemple simple:
const parent = {
foo ( ) {
console . log ( "Hello from the Parent" ) ;
}
}
const child = {
foo ( ) {
super . foo ( ) ;
console . log ( "Hello from the Child" ) ;
}
}
Object . setPrototypeOf ( child , parent ) ;
child . foo ( ) ; // Hello from the Parent
// Hello from the ChildES6 introduit un moyen plus facile d'ajouter des interpolations qui sont évaluées automatiquement.
`${ ... }` est utilisé pour rendre les variables.` Backtick est utilisé comme délimiteur. let user = 'Kevin' ;
console . log ( `Hi ${ user } !` ) ; // Hi Kevin!for...of d'itérates sur des objets itérables, comme le tableau. const nicknames = [ 'di' , 'boo' , 'punkeye' ] ;
nicknames . size = 3 ;
for ( let nickname of nicknames ) {
console . log ( nickname ) ;
}
// di
// boo
// punkeyefor...in itérate sur toutes les propriétés énumérées d'un objet. const nicknames = [ 'di' , 'boo' , 'punkeye' ] ;
nicknames . size = 3 ;
for ( let nickname in nicknames ) {
console . log ( nickname ) ;
}
// 0
// 1
// 2
// size ES6 introduit un nouvel ensemble de structures de données appelées Map et WeakMap . Maintenant, nous utilisons en fait des cartes en JavaScript tout le temps. En fait, chaque objet peut être considéré comme une Map .
Un objet est fait de touches (toujours des chaînes) et de valeurs, tandis que dans Map , toute valeur (à la fois objets et valeurs primitives) peut être utilisée comme clé ou une valeur. Jetez un œil à ce morceau de code:
const myMap = new Map ( ) ;
const keyString = "a string" ,
keyObj = { } ,
keyFunc = ( ) => { } ;
// setting the values
myMap . set ( keyString , "value associated with 'a string'" ) ;
myMap . set ( keyObj , "value associated with keyObj" ) ;
myMap . set ( keyFunc , "value associated with keyFunc" ) ;
myMap . size ; // 3
// getting the values
myMap . get ( keyString ) ; // "value associated with 'a string'"
myMap . get ( keyObj ) ; // "value associated with keyObj"
myMap . get ( keyFunc ) ; // "value associated with keyFunc"Faible map
Une WeakMap est une carte dans laquelle les clés sont faiblement référencées, ce qui n'empêche pas ses clés d'être collectées à ordures. Cela signifie que vous n'avez pas à vous soucier des fuites de mémoire.
Une autre chose à noter ici - dans WeakMap , par opposition à Map chaque clé doit être un objet .
Un WeakMap n'a que quatre méthodes delete(key) , has(key) , get(key) et set(key, value) .
const w = new WeakMap ( ) ;
w . set ( 'a' , 'b' ) ;
// Uncaught TypeError: Invalid value used as weak map key
const o1 = { } ,
o2 = ( ) => { } ,
o3 = window ;
w . set ( o1 , 37 ) ;
w . set ( o2 , "azerty" ) ;
w . set ( o3 , undefined ) ;
w . get ( o3 ) ; // undefined, because that is the set value
w . has ( o1 ) ; // true
w . delete ( o1 ) ;
w . has ( o1 ) ; // falseLes objets définis sont des collections de valeurs uniques. Les valeurs en double sont ignorées, car la collection doit avoir toutes les valeurs uniques. Les valeurs peuvent être des types primitifs ou des références d'objets.
const mySet = new Set ( [ 1 , 1 , 2 , 2 , 3 , 3 ] ) ;
mySet . size ; // 3
mySet . has ( 1 ) ; // true
mySet . add ( 'strings' ) ;
mySet . add ( { a : 1 , b : 2 } ) ; Vous pouvez itérer sur un ordre d'insertion ensemble en utilisant la méthode forEach ou la for...of boucle.
mySet . forEach ( ( item ) => {
console . log ( item ) ;
// 1
// 2
// 3
// 'strings'
// Object { a: 1, b: 2 }
} ) ;
for ( let value of mySet ) {
console . log ( value ) ;
// 1
// 2
// 3
// 'strings'
// Object { a: 1, b: 2 }
} Les ensembles ont également les méthodes delete() et clear() .
Faible
Semblable à WeakMap , l'objet WeakSet vous permet de stocker des objets faiblement tenus dans une collection. Un objet dans le WeakSet ne se produit qu'une seule fois; Il est unique dans la collection de la faiblesse.
const ws = new WeakSet ( ) ;
const obj = { } ;
const foo = { } ;
ws . add ( window ) ;
ws . add ( obj ) ;
ws . has ( window ) ; // true
ws . has ( foo ) ; // false, foo has not been added to the set
ws . delete ( window ) ; // removes window from the set
ws . has ( window ) ; // false, window has been removedES6 présente une nouvelle syntaxe de classe. Une chose à noter ici est que la classe ES6 n'est pas un nouveau modèle d'héritage orienté objet. Ils servent simplement de sucre syntaxique par rapport à l'héritage basé sur le prototype existant de JavaScript.
Une façon de regarder une classe dans ES6 n'est qu'une nouvelle syntaxe pour travailler avec des prototypes et des fonctions de constructeur que nous utiliserions dans ES5.
Fonctions définies à l'aide du mot-clé static Implémentez les fonctions statiques / classes sur la classe.
class Task {
constructor ( ) {
console . log ( "task instantiated!" ) ;
}
showId ( ) {
console . log ( 23 ) ;
}
static loadAll ( ) {
console . log ( "Loading all tasks.." ) ;
}
}
console . log ( typeof Task ) ; // function
const task = new Task ( ) ; // "task instantiated!"
task . showId ( ) ; // 23
Task . loadAll ( ) ; // "Loading all tasks.."s'étend et super dans les classes
Considérez le code suivant:
class Car {
constructor ( ) {
console . log ( "Creating a new car" ) ;
}
}
class Porsche extends Car {
constructor ( ) {
super ( ) ;
console . log ( "Creating Porsche" ) ;
}
}
let c = new Porsche ( ) ;
// Creating a new car
// Creating Porsche extends permettent à la classe infantile de hériter de la classe parent dans ES6. Il est important de noter que le constructeur dérivé doit appeler super() .
Vous pouvez également appeler la méthode de la classe Parent dans les méthodes de la classe enfant en utilisant super.parentMethodName()
En savoir plus sur les cours ici
Quelques choses à garder à l'esprit:
function lors de la définition des fonctions dans une définition de classe. Un Symbol est un type de données unique et immuable introduit dans ES6. Le but d'un symbole est de générer un identifiant unique, mais vous ne pouvez jamais avoir accès à cet identifiant.
Voici comment vous créez un symbole:
const sym = Symbol ( "some optional description" ) ;
console . log ( typeof sym ) ; // symbol Notez que vous ne pouvez pas utiliser new avec Symbol(…) .
Si un symbole est utilisé comme propriété / clé d'un objet, il est stocké de manière spéciale que la propriété n'apparaîtra pas dans une énumération normale des propriétés de l'objet.
const o = {
val : 10 ,
[ Symbol ( "random" ) ] : "I'm a symbol" ,
} ;
console . log ( Object . getOwnPropertyNames ( o ) ) ; // val Pour récupérer les propriétés des symboles d'un objet, utilisez Object.getOwnPropertySymbols(o)
Un itérateur accède aux éléments d'une collection un à la fois, tout en gardant une trace de sa position actuelle dans cette séquence. Il fournit une méthode next() qui renvoie l'élément suivant dans la séquence. Cette méthode renvoie un objet avec deux propriétés: terminé et valeur.
ES6 a Symbol.iterator qui spécifie l'itérateur par défaut pour un objet. Chaque fois qu'un objet doit être itéré (comme au début d'une boucle pour..of), sa méthode d'Iterator @@ est appelé sans arguments, et l'itérateur retourné est utilisé pour obtenir les valeurs à itérer.
Regardons un tableau, qui est un itérable, et l'itérateur qu'il peut produire pour consommer ses valeurs:
const arr = [ 11 , 12 , 13 ] ;
const itr = arr [ Symbol . iterator ] ( ) ;
itr . next ( ) ; // { value: 11, done: false }
itr . next ( ) ; // { value: 12, done: false }
itr . next ( ) ; // { value: 13, done: false }
itr . next ( ) ; // { value: undefined, done: true } Notez que vous pouvez écrire des itérateurs personnalisés en définissant obj[Symbol.iterator]() avec la définition de l'objet.
Les fonctions du générateur sont une nouvelle fonctionnalité dans ES6 qui permet à une fonction de générer de nombreuses valeurs au fil du temps en renvoyant un objet qui peut être itéré pour extraire les valeurs de la fonction une valeur à la fois.
Une fonction de générateur renvoie un objet itérable lorsqu'il s'appelle. Il est écrit en utilisant la nouvelle syntaxe * ainsi que le nouveau mot clé yield introduit dans ES6.
function * infiniteNumbers ( ) {
let n = 1 ;
while ( true ) {
yield n ++ ;
}
}
const numbers = infiniteNumbers ( ) ; // returns an iterable object
numbers . next ( ) ; // { value: 1, done: false }
numbers . next ( ) ; // { value: 2, done: false }
numbers . next ( ) ; // { value: 3, done: false }Chaque rendement dans le temps est appelé, la valeur donnée devient la valeur suivante de la séquence.
Notez également que les générateurs calculent leurs valeurs cédées à la demande, ce qui leur permet de représenter efficacement des séquences coûteuses à calculer, voire des séquences infinies.
ES6 a un soutien natif pour les promesses. Une promesse est un objet qui attend qu'une opération asynchrone se termine, et à la fin de cette opération, la promesse est tenue (résolue) ou rejetée.
La façon standard de créer une promesse consiste à utiliser le new Promise() qui accepte un gestionnaire qui reçoit deux fonctions comme paramètres. Le premier gestionnaire (généralement nommé resolve ) est une fonction à appeler avec la valeur future lorsqu'elle est prête; et le deuxième gestionnaire (généralement nommé reject ) est une fonction à appeler pour rejeter la promesse si elle ne peut pas résoudre la valeur future.
const p = new Promise ( ( resolve , reject ) => {
if ( /* condition */ ) {
resolve ( /* value */ ) ; // fulfilled successfully
} else {
reject ( /* reason */ ) ; // error, rejected
}
} ) ; Chaque promesse a then une méthode nommée qui prend une paire de rappels. Le premier rappel est appelé si la promesse est résolue, tandis que la seconde est appelée si la promesse est rejetée.
p . then ( ( val ) => console . log ( "Promise Resolved" , val ) ,
( err ) => console . log ( "Promise Rejected" , err ) ) ; Le renvoi d'une valeur à partir de then des rappels passera la valeur au rappel suivant then .
const hello = new Promise ( ( resolve , reject ) => { resolve ( "Hello" ) } ) ;
hello . then ( ( str ) => ` ${ str } World` )
. then ( ( str ) => ` ${ str } !` )
. then ( ( str ) => console . log ( str ) ) // Hello World!Lors du retour d'une promesse, la valeur résolue de la promesse sera transmise au prochain rappel pour les enchaîner efficacement. Il s'agit d'une technique simple pour éviter "l'enfer de rappel".
const p = new Promise ( ( resolve , reject ) => { resolve ( 1 ) } ) ;
const eventuallyAdd1 = ( val ) => new Promise ( ( resolve , reject ) => { resolve ( val + 1 ) } ) ;
p . then ( eventuallyAdd1 )
. then ( eventuallyAdd1 )
. then ( ( val ) => console . log ( val ) ) ; // 3