Home > Web Front-end > JS Tutorial > Parsing destructuring assignment in the ES6 version of JavaScript_Basics

Parsing destructuring assignment in the ES6 version of JavaScript_Basics

WBOY
Release: 2016-05-16 15:48:33
Original
1312 people have browsed it

What is destructuring assignment?

Destructuring assignment allows you to assign array and object property values ​​to a series of variables using syntax similar to array or object literals. This syntax is very concise and clearer than traditional property access.

Access the first three items of an array without using destructuring assignment:

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

After using destructuring assignment, the corresponding code becomes more concise and readable:

var [first, second, third] = someArray;
 
var [first, second, third] = someArray;
Copy after login

SpiderMonkey (Firefox’s JavaScript engine) already supports most of the features of destructuring assignment, but not completely.
Destructuring assignment of arrays and iterable objects

We have seen examples of array destructuring assignment above. The general form of this syntax is:

[ variable1, variable2, ..., variableN ] = array;
 
[ variable1, variable2, ..., variableN ] = array;
Copy after login

This will assign the corresponding items in the array to variable1 to variableN in sequence. If you need to declare variables at the same time, you can add the var, let or const keywords in front of the destructuring expression.

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;
Copy after login

In fact, you can nest to any depth:

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
Copy after login

Also, it is possible to skip certain items in an array:

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

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

Copy after login

You can also use a Rest expression to capture the remaining items in an array:

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]
Copy after login

If the array goes out of bounds or accesses an item that does not exist in the array, you will get the same value as accessing through the array index: undefined.

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

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

Copy after login

Note that the method of array destructuring and assignment also applies to traversable objects:

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

Copy after login

Destructuring assignment of objects

Object destructuring assignment allows you to bind variables to different property values ​​of the object. Specify the name of the property to be bound, followed by the variable to be bound:

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"

Copy after login

When the bound attribute name is the same as the variable name that receives the attribute value, there is another syntactic sugar:

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"
Copy after login

Like arrays, they can also be nested:

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"

Copy after login

When destructuring a property that does not exist, you will get undefined:

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

There is another potential pitfall when using destructuring assignment of objects, there is no variable declaration (no var, let or const keyword) during destructuring assignment:

{ blowUp } = { blowUp: 10 };
// Syntax error
 
{ blowUp } = { blowUp: 10 };
// Syntax error
Copy after login

This is because JavaScript syntax tells the engine that any statement starting with { is a statement block (for example, {console} is a legal statement block). The solution is to wrap the entire statement with a pair of parentheses:

({ safe } = {});
// No errors
 
({ safe } = {});
// No errors
Copy after login

Other situations

When you try to destructure null or undefined, you will get a type error:

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

Copy after login

However, you can destructure other basic types (Boolean, String and Number) and you will get undefined:

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

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

Copy after login

The results may surprise you, but if you look deeper, the reason is actually very simple. When performing object destructuring and assignment, the destructured object will be coerced into Object. Except for null and undefined, other types can be coerced into objects. When performing structure assignment of an array, the destructured object is required to have a traverser.
Default value

You can specify a default value for non-existing properties:

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

Copy after login

Practical Application
Function parameters

As developers, we often use an object containing multiple properties as a function parameter to implement a more flexible API, rather than asking API users to remember some parameters in a specific order. We can use destructuring assignment of objects to avoid attribute access every time a parameter is used:

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

Configuration object

To improve the above example, we can provide default values ​​for the object properties to be destructured. This is very practical for objects that are used as configuration parameters, because many configuration items have a reasonable default value. For example, the second parameter of jQuery's ajax method is a configuration object, which we can implement like this:

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
};
Copy after login

This avoids duplication of code like this: var foo = config.foo || theDefaultFoo;.
Used with iterators

When traversing a Map object, we can use destructuring assignment to traverse [key, value]:

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"

Copy after login

Traverse keys only:

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

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

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

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

Copy after login

Return multiple values

Returns an array, and extracts the return value through destructuring assignment:

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

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

Copy after login

Or, return an object of key-value pairs:

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

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

Copy after login

Both of these are better than using intermediate variables:

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;
Copy after login

Use continuation form:

function returnMultipleValues(k) {
 k(1, 2);
}
returnMultipleValues((foo, bar) => ...);

 
function returnMultipleValues(k) {
 k(1, 2);
}
returnMultipleValues((foo, bar) => ...);

Copy after login

导入 CommonJS 模块的指定部分

还没使用过 ES6 的模块吧,那至少使用过 CommonJS 吧。当导入一个 CommonJS 模块 X 时,模块提供的方法也许多余你实际使用的。使用解构赋值,你可以明确指定你需要使用模块的哪些部分:

const { SourceMapConsumer, SourceNode } = require("source-map");
 
const { SourceMapConsumer, SourceNode } = require("source-map");
Copy after login

如果你使用 ES6 的模块机制,你可以看到 import 声明时有一个类似的语法。
结论

我们看到,解构赋值在很多场景下都很实用。在 Mozilla,我们已经有很多经验。Lars Hansen 在 10 年前就向 Opera 引入了解构赋值,Brendan Eich 在稍微晚点也给 Firefox 添加了支持,最早出现在 Firefox 2 中。因此,解构赋值已经渗透到我们每天对 JS 的使用中,悄悄地使我们的代码更简短、整洁。

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template