Maison  >  Article  >  interface Web  >  Analyse de l'affectation de déstructuration dans la version ES6 de JavaScript_Basics

Analyse de l'affectation de déstructuration dans la version ES6 de JavaScript_Basics

WBOY
WBOYoriginal
2016-05-16 15:48:331233parcourir

Qu'est-ce que la mission de déstructuration ?

L'affectation de déstructuration vous permet d'attribuer des valeurs de propriété de tableau et d'objet à une série de variables en utilisant une syntaxe similaire aux littéraux de tableau ou d'objet. Cette syntaxe est très concise et plus claire que l'accès aux propriétés traditionnel.

Accéder aux trois premiers éléments d'un tableau sans utiliser d'affectation de déstructuration :

var first = someArray[0];
var second = someArray[1];
var third = someArray[2];
 
var first = someArray[0];
var second = someArray[1];
var third = someArray[2];

Après avoir utilisé l'affectation de déstructuration, le code correspondant devient plus concis et lisible :

var [first, second, third] = someArray;
 
var [first, second, third] = someArray;

SpiderMonkey (le moteur JavaScript de Firefox) prend déjà en charge la plupart des fonctionnalités d'affectation de déstructuration, mais pas complètement.
Affectation déstructurante de tableaux et d'objets itérables

Nous avons vu des exemples d'affectation de déstructuration de tableaux ci-dessus. La forme générale de cette syntaxe est :

[ variable1, variable2, ..., variableN ] = array;
 
[ variable1, variable2, ..., variableN ] = array;

Cela attribuera les éléments correspondants du tableau à la variable1 à la variableN dans l'ordre. Si vous devez déclarer des variables en même temps, vous pouvez ajouter les mots-clés var, let ou const devant l'expression de déstructuration.

var [ variable1, variable2, ..., variableN ] = array;
let [ variable1, variable2, ..., variableN ] = array;
const [ variable1, variable2, ..., variableN ] = array;
 
var [ variable1, variable2, ..., variableN ] = array;
let [ variable1, variable2, ..., variableN ] = array;
const [ variable1, variable2, ..., variableN ] = array;

En fait, vous pouvez emboîter à n'importe quelle profondeur :

var [foo, [[bar], baz]] = [1, [[2], 3]];
console.log(foo);
// 1
console.log(bar);
// 2
console.log(baz);
// 3
 
var [foo, [[bar], baz]] = [1, [[2], 3]];
console.log(foo);
// 1
console.log(bar);
// 2
console.log(baz);
// 3

De plus, il est possible de sauter certains éléments d'un tableau :

var [,,third] = ["foo", "bar", "baz"];
console.log(third);
// "baz"

 
var [,,third] = ["foo", "bar", "baz"];
console.log(third);
// "baz"

Vous pouvez également utiliser une expression Rest pour capturer les éléments restants d'un tableau :

var [head, ...tail] = [1, 2, 3, 4];
console.log(tail);
// [2, 3, 4]
 
var [head, ...tail] = [1, 2, 3, 4];
console.log(tail);
// [2, 3, 4]

Si le tableau sort des limites ou accède à un élément qui n'existe pas dans le tableau, vous obtiendrez la même valeur qu'en accédant via l'index du tableau : non défini.

console.log([][0]);
// undefined

var [missing] = [];
console.log(missing);
// undefined
 
console.log([][0]);
// undefined
 
var [missing] = [];
console.log(missing);
// undefined

Notez que la méthode de déstructuration et d'affectation des tableaux s'applique également aux objets traversables :

function* fibs() {
 var a = 0;
 var b = 1;
 while (true) {
  yield a;
  [a, b] = [b, a + b];
 }
}

var [first, second, third, fourth, fifth, sixth] = fibs();
console.log(sixth);
// 5
 
function* fibs() {
 var a = 0;
 var b = 1;
 while (true) {
  yield a;
  [a, b] = [b, a + b];
 }
}
 
var [first, second, third, fourth, fifth, sixth] = fibs();
console.log(sixth);
// 5

Affectation déstructurante d'objets

L'affectation de déstructuration d'objet vous permet de lier des variables à différentes valeurs de propriété de l'objet. Précisez le nom de la propriété à lier, suivi de la variable à lier :

var robotA = { name: "Bender" };
var robotB = { name: "Flexo" };

var { name: nameA } = robotA;
var { name: nameB } = robotB;

console.log(nameA);
// "Bender"
console.log(nameB);
// "Flexo"
 
var robotA = { name: "Bender" };
var robotB = { name: "Flexo" };
 
var { name: nameA } = robotA;
var { name: nameB } = robotB;
 
console.log(nameA);
// "Bender"
console.log(nameB);
// "Flexo"

Lorsque le nom de l'attribut lié est le même que le nom de la variable qui reçoit la valeur de l'attribut, il existe un autre sucre syntaxique :

var { foo, bar } = { foo: "lorem", bar: "ipsum" };
console.log(foo);
// "lorem"
console.log(bar);
// "ipsum"
 
var { foo, bar } = { foo: "lorem", bar: "ipsum" };
console.log(foo);
// "lorem"
console.log(bar);
// "ipsum"

Comme les tableaux, ils peuvent également être imbriqués :

var complicatedObj = {
 arrayProp: [
  "Zapp",
  { second: "Brannigan" }
 ]
};

var { arrayProp: [first, { second }] } = complicatedObj;

console.log(first);
// "Zapp"
console.log(second);
// "Brannigan"
 
var complicatedObj = {
 arrayProp: [
  "Zapp",
  { second: "Brannigan" }
 ]
};
 
var { arrayProp: [first, { second }] } = complicatedObj;
 
console.log(first);
// "Zapp"
console.log(second);
// "Brannigan"

Lors de la déstructuration d'un bien qui n'existe pas, vous obtiendrez undéfini :

var { missing } = {};
console.log(missing);
// undefined
 
var { missing } = {};
console.log(missing);
// undefined

Il existe un autre piège potentiel lors de l'utilisation de l'affectation de déstructuration d'objets, il n'y a pas de déclaration de variable (pas de mot-clé var, let ou const) lors de l'affectation de déstructuration :

{ blowUp } = { blowUp: 10 };
// Syntax error
 
{ blowUp } = { blowUp: 10 };
// Syntax error

En effet, la syntaxe JavaScript indique au moteur que toute instruction commençant par { est un bloc d'instructions (par exemple, {console} est un bloc d'instructions légales. La solution consiste à envelopper l'intégralité de l'instruction avec une paire de parenthèses :

({ safe } = {});
// No errors
 
({ safe } = {});
// No errors

Autres situations

Lorsque vous essayez de déstructurer null ou undefined, vous obtiendrez une erreur de type :

var {blowUp} = null;
// TypeError: null has no properties
 
var {blowUp} = null;
// TypeError: null has no properties

Cependant, vous pouvez déstructurer d'autres types de base (Booléen, Chaîne et Nombre) et vous obtiendrez undéfini :


var {wtf} = NaN;
console.log(wtf);
// undefined

 
var {wtf} = NaN;
console.log(wtf);
// undefined

Les résultats peuvent vous surprendre, mais si vous regardez de plus près, la raison est en réalité très simple. Lors de la déstructuration et de l'affectation d'un objet, l'objet déstructuré sera contraint en objet, à l'exception des objets null et non définis, d'autres types peuvent être contraints en objets. Lors de l'affectation de la structure d'un tableau, l'objet déstructuré doit avoir un traverseur.


Valeur par défaut

Vous pouvez spécifier une valeur par défaut pour les propriétés inexistantes :


var [missing = true] = [];
console.log(missing);
// true

var { message: msg = "Something went wrong" } = {};
console.log(msg);
// "Something went wrong"

var { x = 3 } = {};
console.log(x);
// 3
 
var [missing = true] = [];
console.log(missing);
// true
 
var { message: msg = "Something went wrong" } = {};
console.log(msg);
// "Something went wrong"
 
var { x = 3 } = {};
console.log(x);
// 3

Application pratique Paramètres de fonction

En tant que développeurs, nous utilisons souvent un objet contenant plusieurs propriétés comme paramètre de fonction pour implémenter une API plus flexible, plutôt que de demander aux utilisateurs de l'API de mémoriser certains paramètres dans un ordre spécifique. Nous pouvons utiliser l'affectation déstructurante des objets pour éviter l'accès aux attributs à chaque fois qu'un paramètre est utilisé :


function removeBreakpoint({ url, line, column }) {
 // ...
}
 
function removeBreakpoint({ url, line, column }) {
 // ...
}

Objet de configuration

Pour améliorer l'exemple ci-dessus, nous pouvons fournir des valeurs par défaut pour les propriétés de l'objet à déstructurer. Ceci est très pratique pour les objets qui sont utilisés comme paramètres de configuration, car de nombreux éléments de configuration ont une valeur par défaut raisonnable. Par exemple, le deuxième paramètre de la méthode ajax de jQuery est un objet de configuration, que nous pouvons implémenter comme ceci :


jQuery.ajax = function (url, {
 async = true,
 beforeSend = noop,
 cache = true,
 complete = noop,
 crossDomain = false,
 global = true,
 // ... more config
}) {
 // ... do stuff
};
 
jQuery.ajax = function (url, {
 async = true,
 beforeSend = noop,
 cache = true,
 complete = noop,
 crossDomain = false,
 global = true,
 // ... more config
}) {
 // ... do stuff
};
Cela évite la duplication de code comme ceci : var foo = config.foo || theDefaultFoo;.


Utilisé avec les itérateurs

Lors de la traversée d'un objet Map, nous pouvons utiliser une affectation de déstructuration pour parcourir [clé, valeur] :


var map = new Map();
map.set(window, "the global");
map.set(document, "the document");

for (var [key, value] of map) {
 console.log(key + " is " + value);
}
// "[object Window] is the global"
// "[object HTMLDocument] is the document"

 
var map = new Map();
map.set(window, "the global");
map.set(document, "the document");
 
for (var [key, value] of map) {
 console.log(key + " is " + value);
}
// "[object Window] is the global"
// "[object HTMLDocument] is the document"

Touches de déplacement uniquement :


for (var [key] of map) {
 // ...
}

 
for (var [key] of map) {
 // ...
}

只遍历值:
for (var [,value] of map) {
 // ...
}

 
for (var [,value] of map) {
 // ...
}

Renvoyer plusieurs valeurs

Renvoie un tableau et extrait la valeur de retour via une affectation de déstructuration :


function returnMultipleValues() {
 return [1, 2];
}
var [foo, bar] = returnMultipleValues();

 
function returnMultipleValues() {
 return [1, 2];
}
var [foo, bar] = returnMultipleValues();

Ou renvoyez un objet de paires clé-valeur :


function returnMultipleValues() {
 return {
  foo: 1,
  bar: 2
 };
}
var { foo, bar } = returnMultipleValues();

 
function returnMultipleValues() {
 return {
  foo: 1,
  bar: 2
 };
}
var { foo, bar } = returnMultipleValues();

Ces deux sont meilleurs que l'utilisation de variables intermédiaires :


function returnMultipleValues() {
 return {
  foo: 1,
  bar: 2
 };
}
var temp = returnMultipleValues();
var foo = temp.foo;
var bar = temp.bar;
 
function returnMultipleValues() {
 return {
  foo: 1,
  bar: 2
 };
}
var temp = returnMultipleValues();
var foo = temp.foo;
var bar = temp.bar;
Utiliser le formulaire de continuation :


function returnMultipleValues(k) {
 k(1, 2);
}
returnMultipleValues((foo, bar) => ...);

 
function returnMultipleValues(k) {
 k(1, 2);
}
returnMultipleValues((foo, bar) => ...);

导入 CommonJS 模块的指定部分

还没使用过 ES6 的模块吧,那至少使用过 CommonJS 吧。当导入一个 CommonJS 模块 X 时,模块提供的方法也许多余你实际使用的。使用解构赋值,你可以明确指定你需要使用模块的哪些部分:

const { SourceMapConsumer, SourceNode } = require("source-map");
 
const { SourceMapConsumer, SourceNode } = require("source-map");

如果你使用 ES6 的模块机制,你可以看到 import 声明时有一个类似的语法。
结论

我们看到,解构赋值在很多场景下都很实用。在 Mozilla,我们已经有很多经验。Lars Hansen 在 10 年前就向 Opera 引入了解构赋值,Brendan Eich 在稍微晚点也给 Firefox 添加了支持,最早出现在 Firefox 2 中。因此,解构赋值已经渗透到我们每天对 JS 的使用中,悄悄地使我们的代码更简短、整洁。

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn