Maison > interface Web > js tutoriel > le corps du texte

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

小云云
Libérer: 2018-02-08 13:07:32
original
1420 Les gens l'ont consulté

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 // []
Copier après la connexion

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];
Copier après la connexion

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
Copier après la connexion

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] = {};
Copier après la connexion

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;
Copier après la connexion

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"
Copier après la connexion

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
Copier après la connexion

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'
Copier après la connexion

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
Copier après la connexion

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];
}
Copier après la connexion

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
Copier après la connexion

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"
Copier après la connexion

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
Copier après la connexion

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" };
Copier après la connexion

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
Copier après la connexion

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"
Copier après la connexion

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}); // 成功
Copier après la connexion

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"
Copier après la connexion

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
Copier après la connexion

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]
Copier après la connexion

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"
Copier après la connexion

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
Copier après la connexion

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

var {foo} = {bar: 'baz'};
foo // undefined
Copier après la connexion

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'};
Copier après la connexion

à 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});
Copier après la connexion

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;
Copier après la connexion

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"
Copier après la connexion

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
Copier après la connexion

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
Copier après la connexion

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
Copier après la connexion

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
Copier après la connexion

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]
Copier après la connexion

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]
Copier après la connexion

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 } };
Copier après la connexion

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

// 报错
function f([(z)]) { return z; }
Copier après la connexion

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

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

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

// 全部报错
({ p: a }) = { p: 42 };
([a]) = [5];
Copier après la connexion

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

[({ p: a }), { x: c }] = [{}, {}];
Copier après la connexion

可以使用圆括号的况

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

[(b)] = [3]; // 正确
({ p: (d) } = {}); // 正确
[(parseInt.prop)] = [3]; // 正确
Copier après la connexion

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

用途

1.交换变量的值

[x, y] = [y, x];
Copier après la connexion

2.从函数返回多个值

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

3.函数参数的定义

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

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

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]
Copier après la connexion

5.函数参数的默认值

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

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) {
// ...
}
Copier après la connexion

7.输入模块的指定方法

const { SourceMapConsumer, SourceNode } = require("source-map")
Copier après la connexion

相关推荐:

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal