Skip to main content

destructuring (Destructuring Assignment)_ES6 Notes 5

Free2016-04-24#JS#es6解构#js解构#js destructuring#es6析构#js析构

Basic syntax sugar of es6, simple and easy to use

I. Objective

Extract values from objects or arrays and assign to other variables, previously had to do this:

var arr = [1, 2, 3, 4];
var first = arr[0];
var senond = arr[1];
var third = arr[3];

Decompose array to get element values, and assign. The above process is: destructuring-assignment

ES6 proposes new concept: destructuring (destructuring assignment), can make the above process have better readability, avoid code like "hard-coding" style

II. iterable Destructuring

var/let/const [var1, var2...] = iterable syntax indicates declaring variables while performing array/iterator destructuring assignment

Destructured value must be iterable, can conveniently make custom objects become iterable through generator syntax (see [An Yu Qing Yang: for...of Loop_ES6 Notes 1](/articles/for-of 循环-es6 笔记 1/#articleHeader5)), iterable destructuring features are as follows:

  • Can destructure arbitrarily deep nested arrays

  • Can leave empty positions to skip certain elements

  • Can use rest parameters (...var syntax, details please check [An Yu Qing Yang: Default Parameters and Rest Parameters_ES6 Notes 4](/articles/默认参数和不定参数-es6 笔记 4/)) to capture all remaining elements

For example:

// Array
var [[first, [second]], third] = [[1, [2]], 4];
console.log(`first = ${first}`);    // 1
console.log(`second = ${second}`);  // 2
console.log(`third = ${third}`);    // 4

// iterable
var iter = (function*(start) {
    while (true) {
        yield start++;
    }
})(0);
var [v1, v2, v3, v4] = iter;
console.log(`v1 = ${v1}`);  // 0
console.log(`v2 = ${v2}`);  // 1
console.log(`v3 = ${v3}`);  // 2
console.log(`v4 = ${v4}`);  // 3

// Skip elements, capture remaining elements
var arr = [1, 2, 3, 4];
var [, sec, ...aRest] = arr;
console.log(`sec = ${sec}`);        // 2
console.log(`aRest = ${aRest}`);    // [3, 4]

Code like "hard-coding" style is all gone, and destructuring assignment is more clear and intuitive (left-right correspondence)

III. Object Destructuring

var/let/const {key: varName, ...} = obj syntax indicates object destructuring

Special note: Assignment order is from left to right, actual effect is: varName = obj[key]

Destructured value must be able to be forcibly converted to object, so destructuring undefined/null will report error TypeError

Object destructuring features are as follows:

  • When variable name is consistent with object property name can be abbreviated

  • Can only assign to specific property names (no need to leave empty positions to skip)

  • Supports complex nesting (object+array)

For example:

// obj
var obj = {name: 'aae', age: 12, sex: 'F'};
// Only assign to specific property names
var {name: mName, sex: mSex} = obj;
console.log(`mName = ${mName}`);    // mName = aae
console.log(`mSex = ${mSex}`);      // mSex = F
// Abbreviate when variable name is same as property name
var {name, sex} = obj;
console.log(`name = ${name}`);      // name = aae
console.log(`sex = ${sex}`);        // sex = F

Note, if destructuring assignment left side has no var/let/const (i.e. forgot to declare variable, or variable already exists and don't want to declare again), will cause syntax error, as follows:

// var key;

{key} = {key: 'val'};
// Error: Uncaught SyntaxError: Unexpected token =(…)

Because {key} on left side of assignment will be parsed as a block ({}), solution to avoid this behavior is add parentheses around destructuring assignment, for example:

({key} = {key: 'val'});
console.log(`key = ${key}`);    // key = val

Everything inside parentheses are expressions, {key} won't be misparsed as block

IV. Destructuring While Setting Default Values

Syntax similar to default parameter syntax, for example:

// default val
var [val = 'default val'] = [];
var {key: val = 'default val'} = {};
// When property names are same can abbreviate to
// FF43, 45 both don't support, thinkjs, Chrome50 support
// var {val = 'default val'} = {};
console.log(`val = ${val}`);

One statement both sets default value, and destructuring assignment, but syntax is somewhat difficult to read in more complex cases (such as above var {key: val = 'default val'} = {};)

V. Summary

This feature also belongs to icing on the cake things, reduces code like "hard-coding" style, enhances its readability

Uses:

  • Object parameters in function definitions, such as function ajax(config), after changing to function ajax({url, data, callback}) API readability is better, very convenient with default values (avoids operations like var attr = config.attr || defultVal;)

  • Cooperate with iterators, very convenient to traverse map ([key, val] traverse key-value pairs, [key] traverse key set, [, val] traverse value set)

  • Implement functions returning multiple values (return array, destructure into individual variables when accepting return value)

  • Import part of CommonJS modules, only destructure the parts needed. ES6 module import supports similar functionality

For example:

// use
// 1
function ajax({url, data, callback}) {
    console.log(`ajax(${url}, ${data}, ${callback})`);
}
ajax({url: 'www.xxx.xx', data: 'data'});
// log print: ajax(www.xxx.xx, data, undefined)

// 2
for (var [key, val] of new Map([['name', 'eea'], ['age', 12]])) {
    console.log(`key = ${key}, val = ${val}`);
}
// log print: key = name, val = eea
//            key = age, val = 12

// 3
var [res1, res2] = (function() {
    return [1, {a: 1}];
})();
console.log(`res1 = ${res1}, res2 = ${res2}`);
// res1 = 1, res2 = [object Object]

Reference Materials

  • "ES6 in Depth": Free e-book provided by InfoQ Chinese site

Comments

No comments yet. Be the first to share your thoughts.

Leave a comment