Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung der destrukturierenden Zuweisung von ECMAScript6-Variablen

Detaillierte Erläuterung der destrukturierenden Zuweisung von ECMAScript6-Variablen

小云云
小云云Original
2018-02-08 13:07:321395Durchsuche

ES6 ermöglicht das Extrahieren von Werten aus Arrays und Objekten und das Zuweisen von Werten zu Variablen nach bestimmten Mustern. Dieser Artikel zeigt Ihnen hauptsächlich Beispiele für die Destrukturierung verschachtelter Arrays , b, c] = [1, 2, 3];

Diese Schreibweise gehört zum „Mustervergleich“. Der Variablen links wird der entsprechende Wert zugewiesen.

Im Folgenden finden Sie einige Beispiele für die Destrukturierung mithilfe verschachtelter Arrays.

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 // []

Wenn die Destrukturierung nicht erfolgreich ist, ist der Wert der Variablen gleich undefiniert.

Der Wert von foo ist gleich undefiniert

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

Unvollständige Dekonstruktion bedeutet, dass das Muster auf der linken Seite des Gleichheitszeichens nur mit einem Teil des Arrays auf der rechten Seite des Gleichheitszeichens übereinstimmt

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

Wenn die rechte Seite des Gleichheitszeichens kein Array ist, wird ein Fehler gemeldet.

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

Die destrukturierende Zuweisung gilt nicht nur für den Befehl var, sondern auch für die Befehle let und const.

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

Für die Set-Struktur kann auch die destrukturierende Zuweisung des Arrays verwendet werden.

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

Solange eine bestimmte Datenstruktur über eine Iterator-Schnittstelle verfügt, kann eine destrukturierende Zuweisung in Form eines Arrays verwendet werden.

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 ist eine Generatorfunktion, die nativ über eine verfügt Iterator-Schnittstelle. Die Destrukturierungszuweisung erhält wiederum den Wert von dieser Schnittstelle

Die Destrukturierungszuweisung ermöglicht die Angabe eines Standardwerts.

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

ES6 verwendet intern den strikten Gleichheitsoperator ( === ), um zu bestimmen, ob eine Position einen Wert hat. Wenn ein Array-Mitglied nicht unbedingt undefiniert ist, wird der Standardwert daher nicht wirksam.

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

Wenn ein Array-Mitglied null ist, wird der Standardwert nicht wirksam, da null nicht unbedingt undefiniert ist

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

Wenn der Standardwert ein Ausdruck ist, dann dieser Ausdruck Es wird träge ausgewertet, das heißt, es wird nur ausgewertet, wenn es verwendet wird

Der Standardwert kann sich auf andere Variablen mit destrukturierender Zuweisung beziehen, aber die Variable muss deklariert worden sein

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

Ja, denn wenn x den Standardwert y verwendet, wurde y noch nicht deklariert

Destrukturierende Zuweisung des Objekts

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

Die Elemente des Arrays sind der Reihe nach angeordnet und Der Wert der Variablen wird durch ihre Position bestimmt. Die Eigenschaften eines Objekts sind nicht in Ordnung, und die Variable muss denselben Namen wie die Eigenschaft haben, um den richtigen Wert zu erhalten.

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

Tatsächlich ist die Die Destrukturierungszuweisung des Objekts ist die Abkürzung der folgenden Form:

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

Der interne Mechanismus der Objektdestrukturierung und -zuweisung besteht darin, zuerst das Attribut mit demselben Namen zu finden und es dann der entsprechenden Variablen zuzuweisen. Was wirklich zugewiesen wird, ist Letzteres, nicht Ersteres

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

Im obigen Code wird wirklich die Variable baz zugewiesen, nicht der Modus foo

Die Deklaration und Zuweisung von Variable werden integriert. Für let und const können Variablen nicht erneut deklariert werden. Sobald die zugewiesene Variable also zuvor deklariert wurde
, wird ein Fehler gemeldet

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

Da der Befehl var eine erneute Deklaration zulässt, wird dieser Fehler nur verwendet Erscheint bei let- und const-Befehlen. Wenn kein zweiter let-Befehl vorhanden ist, meldet der obige Code keinen Fehler

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

Wie Arrays kann die Destrukturierung auch für Objekte mit verschachtelten Strukturen verwendet werden

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

Derzeit p Es ist ein Muster, keine Variable, daher wird ihm kein Wert zugewiesen

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

Nur ​​Zeile ist eine Variable, loc und start sind beide Muster und es wird kein Wert zugewiesen

Ein Beispiel für eine verschachtelte Zuweisung.

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

Die Destrukturierung des Objekts gibt auch einen Standardwert an

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"

Die Bedingung für die Wirksamkeit des Standardwerts ist, dass der Attributwert des Objekts genau gleich undefiniert ist

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

Wenn die Zerstörung fehlschlägt, ist der Wert der Variablen gleich undefiniert

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

Der Destrukturierungsmodus ist ein verschachteltes Objekt und die übergeordnete Eigenschaft des untergeordneten Objekts ist nicht vorhanden , dann wird ein Fehler

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

auf der linken Seite des Gleichheitszeichens gemeldet. Die foo-Eigenschaft des Objekts entspricht einem Unterobjekt. Das Balkenattribut dieses Unterobjekts meldet beim Destrukturieren einen Fehler. Da foo zu diesem Zeitpunkt gleich undefiniert ist, wird bei der Übernahme der Untereigenschaft ein Fehler gemeldet.

Wenn Sie eine deklarierte Variable für die Destrukturierungszuweisung verwenden möchten, müssen Sie sehr vorsichtig sein

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

da die JavaScript-Engine {x} als Codeblock interpretiert, was zu einem Syntaxfehler führt. Dieses Problem kann nur gelöst werden, indem die geschweiften Klammern nicht am Anfang der Zeile geschrieben werden, um zu verhindern, dass JavaScript sie als Codeblöcke interpretiert.

Durch die destrukturierte Zuweisung von Objekten können einer Variablen problemlos Methoden vorhandener Objekte zugewiesen werden

let { log, sin, cos } = Math;

Weisen Sie die Logarithmus-, Sinus- und Cosinus-Methoden des Math-Objekts den entsprechenden Variablen zu, was die Verwendung wesentlich komfortabler macht

Destrukturierung und Zuweisung von Zeichenfolgen

Strings können auch destrukturiert und zugewiesen werden. An diesem Punkt wird die Zeichenfolge in ein Array-ähnliches Objekt umgewandelt

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

Array-ähnliche Objekte haben ein Längenattribut, daher kann dieses Attribut auch dekonstruiert und einem Wert zugewiesen werden

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

eine numerische Wert- und boolesche Wert-Destrukturierungszuweisung

Wenn bei der Destrukturierung der Zuweisung die rechte Seite des Gleichheitszeichens ein numerischer Wert oder ein boolescher Wert ist, wird dieser zuerst in ein Objekt umgewandelt

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

Es gibt sowohl numerische als auch boolesche Wrapping-Objekte in das String-Attribut, sodass die Variablen s alle den Wert annehmen können

Die Regel der destrukturierenden Zuweisung lautet: solange der Wert auf der rechten Seite des Gleichheitszeichens steht kein Objekt ist, konvertieren Sie es zuerst in ein Objekt. Da undefiniert und null nicht in Objekte konvertiert werden können, führt deren Destrukturierung und Zuweisung zu einem Fehler.

let { prop: x } = undefined; // TypeError
let { prop: y } = null; // TypeError

Destrukturierende Zuweisung von Funktionsparametern

function add([x, y]){
  return x + y;
}
add([1, 2]); // 3

Destrukturierende Funktionsparameter können auch Standardwerte verwenden

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]

Der Parameter der Funktionsbewegung ist ein Objekt, bestanden Dekonstruieren Sie dieses Objekt und erhalten Sie die Werte der Variablen x und y. Wenn die Destrukturierung fehlschlägt, sind x und y gleich dem Standardwert.

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]

gibt den Standardwert für die Parameter der Funktion move an, anstatt den Standardwert für die Variablen x und y anzugeben, also Sie wird eine andere Schreibmethode als das vorherige Ergebnis erhalten. undefiniert löst den Standardwert des Funktionsparameters aus

das Klammerproblem

解构赋值虽然很方便,但是解析起来并不容易。对于编译器来说,一个式子到底是模式,还是表达式,没有办法从一开始就知道,必须解析到(或解析不到)等号才能知道如果模式中出现圆括号怎么处理。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技巧

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der destrukturierenden Zuweisung von ECMAScript6-Variablen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn