Heim  >  Artikel  >  Web-Frontend  >  Analyse der Destrukturierungszuweisung in der ES6-Version von JavaScript_Basics

Analyse der Destrukturierungszuweisung in der ES6-Version von JavaScript_Basics

WBOY
WBOYOriginal
2016-05-16 15:48:331233Durchsuche

Was ist eine Destrukturierungsaufgabe?

Durch die Destrukturierung der Zuweisung können Sie einer Reihe von Variablen Array- und Objekteigenschaftswerte zuweisen, wobei Sie eine Syntax verwenden, die Array- oder Objektliteralen ähnelt. Diese Syntax ist sehr prägnant und klarer als der herkömmliche Zugriff auf Eigenschaften.

Greifen Sie auf die ersten drei Elemente eines Arrays zu, ohne eine destrukturierende Zuweisung zu verwenden:

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

Nach der Verwendung der destrukturierenden Zuweisung wird der entsprechende Code prägnanter und lesbarer:

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

SpiderMonkey (die JavaScript-Engine von Firefox) unterstützt bereits die meisten Funktionen der Destrukturierungszuweisung, jedoch nicht vollständig.
Destrukturierende Zuweisung von Arrays und iterierbaren Objekten

Wir haben oben Beispiele für die Zuweisung einer Array-Destrukturierung gesehen. Die allgemeine Form dieser Syntax ist:

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

Dadurch werden die entsprechenden Elemente im Array nacheinander Variable1 bis VariableN zugewiesen. Wenn Sie gleichzeitig Variablen deklarieren müssen, können Sie die Schlüsselwörter var, let oder const vor dem Destrukturierungsausdruck hinzufügen.

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;

Tatsächlich können Sie jede Tiefe verschachteln:

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

Außerdem ist es möglich, bestimmte Elemente in einem Array zu überspringen:

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

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

Sie können auch einen Rest-Ausdruck verwenden, um die verbleibenden Elemente in einem Array zu erfassen:

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]

Wenn das Array außerhalb der Grenzen liegt oder auf ein Element zugreift, das nicht im Array vorhanden ist, erhalten Sie denselben Wert wie beim Zugriff über den Array-Index: undefiniert.

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

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

Beachten Sie, dass die Methode der Array-Destrukturierung und -Zuweisung auch für durchquerbare Objekte gilt:

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

Destrukturierende Zuordnung von Objekten

Die Objektdestrukturierungszuweisung ermöglicht es Ihnen, Variablen an verschiedene Eigenschaftswerte des Objekts zu binden. Geben Sie den Namen der zu bindenden Eigenschaft an, gefolgt von der zu bindenden Variablen:

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"

Wenn der gebundene Attributname mit dem Variablennamen übereinstimmt, der den Attributwert empfängt, gibt es einen weiteren syntaktischen Zucker:

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"

Wie Arrays können sie auch verschachtelt werden:

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"

Wenn Sie eine Eigenschaft zerstören, die nicht existiert, erhalten Sie undefiniert:

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

Es gibt eine weitere potenzielle Gefahr bei der Verwendung der destrukturierenden Zuweisung von Objekten: Es gibt keine Variablendeklaration (kein Schlüsselwort var, let oder const) während der destrukturierenden Zuweisung:

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

Dies liegt daran, dass die JavaScript-Syntax der Engine mitteilt, dass jede Anweisung, die mit { beginnt, ein Anweisungsblock ist (zum Beispiel ist {console} ein zulässiger Anweisungsblock. Die Lösung besteht darin, die gesamte Anweisung mit einem Klammerpaar zu umschließen:

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

Andere Situationen

Wenn Sie versuchen, null oder undefiniert zu destrukturieren, erhalten Sie einen Typfehler:

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

Sie können jedoch andere Grundtypen (Boolean, String und Number) destrukturieren und erhalten undefiniert:


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

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

Die Ergebnisse mögen Sie überraschen, aber wenn Sie genauer hinschauen, ist der Grund eigentlich ganz einfach. Bei der Objektdestrukturierung und -zuweisung wird das destrukturierte Objekt in ein Objekt umgewandelt. Mit Ausnahme von null und undefiniert können andere Typen in Objekte umgewandelt werden. Bei der Strukturzuweisung eines Arrays muss das destrukturierte Objekt über einen Traverser verfügen.


Standardwert

Sie können einen Standardwert für nicht vorhandene Eigenschaften angeben:


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

Praktische Anwendung Funktionsparameter

Als Entwickler verwenden wir oft ein Objekt, das mehrere Eigenschaften enthält, als Funktionsparameter, um eine flexiblere API zu implementieren, anstatt API-Benutzer zu bitten, sich einige Parameter in einer bestimmten Reihenfolge zu merken. Wir können die destrukturierende Zuweisung von Objekten verwenden, um den Attributzugriff bei jeder Verwendung eines Parameters zu vermeiden:


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

Konfigurationsobjekt

Um das obige Beispiel zu verbessern, können wir Standardwerte für die zu zerstörenden Objekteigenschaften bereitstellen. Dies ist sehr praktisch für Objekte, die als Konfigurationsparameter verwendet werden, da viele Konfigurationselemente einen angemessenen Standardwert haben. Der zweite Parameter der Ajax-Methode von jQuery ist beispielsweise ein Konfigurationsobjekt, das wir wie folgt implementieren können:


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
};
Dadurch wird eine Duplizierung von Code wie folgt vermieden: var foo = config.foo || theDefaultFoo;.


Wird mit Iteratoren verwendet

Beim Durchlaufen eines Map-Objekts können wir eine destrukturierende Zuweisung verwenden, um [Schlüssel, Wert] zu durchqueren:


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"

Nur ​​Verfahrtasten:


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

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

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

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

Mehrere Werte zurückgeben

Gibt ein Array zurück und extrahiert den Rückgabewert durch Destrukturierungszuweisung:


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

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

Oder geben Sie ein Objekt aus Schlüssel-Wert-Paaren zurück:


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

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

Beides ist besser als die Verwendung von Zwischenvariablen:


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;
Fortsetzungsformular verwenden:


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 的使用中,悄悄地使我们的代码更简短、整洁。

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