Maison  >  Article  >  interface Web  >  Explication détaillée de l'affectation de déstructuration des variables ECMAScript6

Explication détaillée de l'affectation de déstructuration des variables ECMAScript6

小云云
小云云original
2018-02-08 13:07:321346parcourir

ES6 permet d'extraire des valeurs de tableaux et d'objets et d'attribuer des valeurs à des variables selon certains modèles. C'est ce qu'on appelle la déstructuration. Cet article partage principalement avec vous des exemples de déstructuration de tableaux imbriqués. , b, c] = [1, 2, 3];

Cette façon d'écrire appartient à la "correspondance de motifs". Tant que les motifs des deux côtés du signe égal sont les mêmes, la variable de gauche se verra attribuer la valeur correspondante.

Voici quelques exemples de déstructuration à l'aide de tableaux imbriqués

let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3
let [ , , third] = ["foo", "bar", "baz"];
third // "baz"
let [x, , y] = [1, 2, 3];
x // 1
y // 3
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []

Si la déstructuration échoue, la valeur de la variable sera égale à undefined

La valeur de foo sera égal à indéfini

var [foo] = [];
var [bar, foo] = [1];

Une déconstruction incomplète signifie que le motif sur le côté gauche du signe égal ne correspond qu'à une partie du tableau sur le côté droit du signe égal

let [x, y] = [1, 2, 3];
x // 1
y // 2
let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4

Si le côté droit du signe égal n'est pas un tableau, une erreur sera signalée.

// 报错let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};

L'affectation de déstructuration n'est pas seulement applicable à la commande var, mais également aux commandes let et const

var [v1, v2, ..., vN ] = array;
let [v1, v2, ..., vN ] = array;
const [v1, v2, ..., vN ] = array;

Pour la structure Set, l'affectation de déstructuration du tableau peut également être utilisée.

let [x, y, z] = new Set(["a", "b", "c"]);
x // "a"

Tant qu'une certaine structure de données possède une interface Itérateur, une affectation de déstructuration sous forme de tableau peut être utilisée

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();
sixth // 5

fibs est une fonction Générateur qui possède nativement un Interface de l'itérateur. L'affectation de déstructuration obtiendra à son tour la valeur de cette interface

L'affectation de déstructuration permet de spécifier une valeur par défaut.

var [foo = true] = [];
foo // true
[x, y = 'b'] = ['a']; // x='a', y='b'
[x, y = 'b'] = ['a', undefined]; // x='a', y='b'

ES6 utilise en interne l'opérateur d'égalité stricte ( === ) pour déterminer si une position a une valeur. Par conséquent, si un membre du tableau n’est pas strictement égal à undefined , la valeur par défaut ne prendra pas effet.

var [x = 1] = [undefined];
x // 1
var [x = 1] = [null];
x // null

Si un membre du tableau est nul, la valeur par défaut ne prendra pas effet, car null n'est pas strictement égal à indéfini

function f() {
console.log('aaa');
}
let [x = f()] = [1];
//等价于
let x;
if ([1][0] === undefined) {
  x = f();
} else {
  x = [1][0];
}

Si la valeur par défaut est une expression, alors cette expression Il est évalué paresseusement, c'est-à-dire qu'il ne sera évalué que lorsqu'il sera utilisé

La valeur par défaut peut faire référence à d'autres variables d'affectation déstructurante, mais la variable doit avoir été déclarée

let [x = 1, y = x] = []; // x=1; y=1
let [x = 1, y = x] = [2]; // x=2; y=2
let [x = 1, y = x] = [1, 2]; // x=1; y=2
let [x = y, y = 1] = []; // ReferenceError

Oui Parce que lorsque x utilise la valeur par défaut y, y n'a pas encore été déclaré

Affectation déstructurante de l'objet

var { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"

Les éléments du tableau sont disposés dans l'ordre, et la valeur de la variable est déterminée par sa position ;Les propriétés d'un objet ne sont pas dans l'ordre, et la variable doit avoir le même nom que la propriété pour obtenir la valeur correcte

var { bar, foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
var { baz } = { foo: "aaa", bar: "bbb" };
baz // undefined

En fait, la l'affectation de déstructuration de l'objet est l'abréviation de la forme suivante

var { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };

Le mécanisme interne de déstructuration et d'affectation d'objet consiste à trouver d'abord l'attribut du même nom puis à l'attribuer à la variable correspondante. Ce qui est réellement assigné, c'est ce dernier, pas le premier

var { foo: baz } = { foo: "aaa", bar: "bbb" };
baz // "aaa"
foo // error: foo is not defined

Dans le code ci-dessus, ce qui est réellement assigné est la variable baz, pas le mode foo

La déclaration et l'affectation du Les variables sont intégrées. Pour let et const, les variables ne peuvent pas être redéclarées, donc une fois la variable affectée préalablement déclarée
, une erreur sera signalée

let foo;
let {foo} = {foo: 1}; 
// SyntaxError: Duplicate declaration "foo"
let baz;
let {bar: baz} = {bar: 1}; 
// SyntaxError: Duplicate declaration "baz"

Parce que la commande var permet la redéclaration, cette erreur ne sera utilisée que Apparaît avec les commandes let et const. S'il n'y a pas de deuxième commande let, le code ci-dessus ne signalera pas d'erreur

let foo;
({foo} = {foo: 1}); // 成功
let baz;
({bar: baz} = {bar: 1}); // 成功

Comme les tableaux, la déstructuration peut également être utilisée pour les objets avec des structures imbriquées

var obj = {
  p: [
   "Hello",
   { y: "World" }
  ]
};
var { p: [x, { y }] } = obj;
x // "Hello"
y // "World"

Pour le moment p C'est un modèle, pas une variable, donc aucune valeur ne lui sera attribuée

var node = {
  loc: {
   start: {
     line: 1,
     column: 5
   }
  }
};
var { loc: { start: { line }} } = node;
line // 1
loc // error: loc is undefined
start // error: start is undefined

Seule la ligne est une variable, loc et start sont tous deux des modèles et aucune valeur ne lui sera attribuée

Un exemple d'affectation imbriquée.

let obj = {};
let arr = [];
({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });
obj // {prop:123}
arr // [true]

La déstructuration de l'objet précise également une valeur par défaut

var {x = 3} = {};
x // 3
var {x, y = 5} = {x: 1};
x // 1
y // 5
var { message: msg = "Something went wrong" } = {};
msg // "Something went wrong"

La condition pour que la valeur par défaut prenne effet est que la valeur d'attribut de l'objet soit strictement égale à indéfini

var {x = 3} = {x: undefined};
x // 3
var {x = 3} = {x: null};
x // null

En cas d'échec de destruction, la valeur de la variable est égale à indéfini

var {foo} = {bar: 'baz'};
foo // undefined

Le mode de déstructuration est un objet imbriqué, et la propriété parent de l'objet enfant n'existe pas , alors une erreur sera signalée

// 报错
var {foo: {bar}} = {baz: 'baz'};

à gauche du signe égal. La propriété foo de l'objet correspond à un sous-objet. L'attribut bar de ce sous-objet signalera une erreur lors de la déstructuration. Parce que foo est égal à undefined à ce moment, une erreur sera signalée lors de la prise de la sous-propriété

Pour utiliser une variable déclarée pour une affectation de déstructuration, vous devez être très prudent

// 错误的写法
var x;
{x} = {x: 1};
// SyntaxError: syntax error
// 正确的写法
({x} = {x: 1});

car le moteur JavaScript interprétera { x} comme un bloc de code, ce qui entraînera une erreur de syntaxe. Ce problème ne peut être résolu qu'en n'écrivant pas les accolades au début de la ligne pour éviter que JavaScript les interprète comme des blocs de code

L'affectation de déstructuration d'objets peut facilement attribuer des méthodes d'objets existants à une variable

.
let { log, sin, cos } = Math;

Attribuez les méthodes logarithme, sinus et cosinus de l'objet Math aux variables correspondantes, ce qui sera beaucoup plus pratique à utiliser

Déstructuration et affectation de chaînes

Chaînes. peut également être déstructuré et cédé. À ce stade, la chaîne est convertie en un objet de type tableau

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

Les objets de type tableau ont un attribut de longueur, donc cet attribut peut également être déconstruit et attribué une valeur

let {length : len} = 'hello';
len // 5

une affectation de déstructuration de valeur numérique et de valeur booléenne

Lors de la déstructuration de l'affectation, si le côté droit du signe égal est une valeur numérique ou une valeur booléenne, il sera d'abord converti en objet

let {toString: s} = 123;
s === Number.prototype.toString // true
let {toString: s} = true;
s === Boolean.prototype.toString // true

Il existe des objets d'empaquetage pour les valeurs numériques et booléennes. le signe égal n'est pas un objet, convertissez-le d'abord en objet. Étant donné qu'undefined et null ne peuvent pas être convertis en objets, leur déstructuration et leur attribution entraîneront une erreur.

Affectation déstructurante des paramètres de fonction
let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError

La déstructuration des paramètres de fonction peut également utiliser des valeurs par défaut
function add([x, y]){
  return x + y;
}
add([1, 2]); // 3

Le paramètre de fonction move est un objet, passé Déconstruisez cet objet et obtenez les valeurs des variables x et y. Si la déstructuration échoue, x et y sont égaux aux valeurs par défaut
function move({x = 0, y = 0} = {}) {
  return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]

spécifie les valeurs par défaut pour les paramètres de la fonction move, plutôt que de spécifier les valeurs par défaut pour les variables x et y, vous obtiendrez donc une méthode d’écriture différente du résultat précédent. undefined déclenchera la valeur par défaut du paramètre de fonction
function move({x, y} = { x: 0, y: 0 }) {
return [x, y];
}
move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, undefined]
move({}); // [undefined, undefined]
move(); // [0, 0]

le problème des parenthèses

解构赋值虽然很方便,但是解析起来并不容易。对于编译器来说,一个式子到底是模式,还是表达式,没有办法从一开始就知道,必须解析到(或解析不到)等号才能知道如果模式中出现圆括号怎么处理。ES6的规则是,只要有可能导致解构的歧义,就不得使用圆括号。但是,这条规则实际上不那么容易辨别,处理起来相当麻烦。因此,建议只要有可能,就不要在模式中放置圆括号

不能使用圆括号的情况

1.变量声明语句中,不能带有圆括号

// 全部报错
var [(a)] = [1];
var {x: (c)} = {};
var ({x: c}) = {};
var {(x: c)} = {};
var {(x): c} = {};}
var { o: ({ p: p }) } = { o: { p: 2 } };

2.函数参数中不能使用圆括号

// 报错
function f([(z)]) { return z; }

3.赋值语句中,不能将整个模式,或嵌

套模式中的一层,放在圆括号之中

将整个模式放在模式之中,导致报错

// 全部报错
({ p: a }) = { p: 42 };
([a]) = [5];

将嵌套模式的一层,放在圆括号之中,导致报错

[({ p: a }), { x: c }] = [{}, {}];

可以使用圆括号的况

赋值语句的非模式部分,可以使用圆括号

[(b)] = [3]; // 正确
({ p: (d) } = {}); // 正确
[(parseInt.prop)] = [3]; // 正确

首先它们都是赋值语句,而不是声明语句;其次它们的圆括号都不属于模式的一部分。第一行语句中,模式是取数组的第一个成员,跟圆括号无关;第二行语句中,模式是p,而不是d;第三行语句与第一行语句的性
质一致

用途

1.交换变量的值

[x, y] = [y, x];

2.从函数返回多个值

// 返回一个数组
function example() {
  return [1, 2, 3];
}
var [a, b, c] = example();
// 返回一个对象
function example() {
  return {
   foo: 1,
   bar: 2
  };
}
var { foo, bar } = example();

3.函数参数的定义

解构赋值可以方便地将一组参数与变量名对应起来

function f([x, y, z]) { ... }
f([1, 2, 3]);
// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});

4.提取JSON数据

var jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
};
let { id, status, data: number } = jsonData;
console.log(id, status, number);
// 42, "OK", [867, 5309]

5.函数参数的默认值

jQuery.ajax = function (url, {
  async = true,
  beforeSend = function () {},
  cache = true,
  complete = function () {},
  crossDomain = false,
  global = true,
  // ... more config
}) {
  // ... do stuff
};

6.便利Map结构

var map = new Map();
map.set('first', 'hello');
map.set('second', 'world');
for (let [key, value] of map) {
  console.log(key + " is " + value);
}
// first is hello
// second is world
// 获取键名
for (let [key] of map) {
// ...
}
// 获取键值
for (let [,value] of map) {
// ...
}

7.输入模块的指定方法

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

相关推荐:

ECMAScript6是什么?

ECMAScript6入门之Class对象的实例详解

ECMAScript6新增值比较函数Object.is_javascript技巧

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

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