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 fonctionlet { prop: x } = undefined; // TypeError let { prop: y } = null; // TypeError
function add([x, y]){ return x + y; } add([1, 2]); // 3
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]
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新增值比较函数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!