ES6 Learning Notes: Deconstructive Assignment of Variables

Keywords: Attribute JSON JQuery

Deconstructive Assignment of Variables

Definition: ES6 allows you to extract values from arrays and objects according to a certain pattern and assign variables, which is called Destructuring.

Basic examples:

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 // []
Advanced examples:

As long as a data structure has an Iterator interface, it can be deconstructed and assigned in the form of arrays.

function* fibs() {
  let a = 0;
  let b = 1;
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

let [first, second, third, fourth, fifth, sixth] = fibs();//[0,1,1,2,3,5]

let x,y;
[ x, y ]= [ 1, x+1 ];
x//1
y//NaN


Here we have to learn Generator first. Functional grammar (this is how it feels when you start a new language. Looking at a knowledge point brings a lot of knowledge points.)

Grammar of Generator Function

Default value:

Deconstruction assignment allows default values to be specified. Note that strict equality operators (===) are used inside ES6 to determine whether a location has a value. Therefore, if an array member is not strictly undefined, the default value will not take effect.

let [foo = true] = [];
//If no default value is set, foo=undefined;
foo // true

let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
If an array member is null, the default value will not take effect because null is not strictly equal to undefined.

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

Object deconstruction assignment

There is an important difference between object deconstruction and array. The elements of an array are arranged in order, and the value of a variable is determined by its position; while the attributes of an object are not in order, the variables must have the same name as the attributes in order to get the correct value.

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

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

//If the variable name is inconsistent with the attribute name, it must be written as follows
var { foo: baz }={ foo:'aaa' , bar: 'bbb' };
baz//"aaa"

let obj={ first: 'hello' ,last:'world' };
let {first: f, last: l }=obj;
f//"hello"
l//"world"
That is to say, the internal mechanism of object deconstruction assignment is to find the same name attribute first, and then assign the corresponding variables. It is the latter, not the former, that is really assigned.

let { foo: baz } = { foo: "aaa", bar: "bbb" };
baz // "aaa"
foo // error: foo is not defined
The parentheses in the next line of the let command are required, otherwise an error will be reported. Because the parser interprets the first braces as a block of code, not an assignment statement.

let a;
{a}={a:1};//error

let foo;
({foo} = {foo: 1}); // Success

let baz;
({bar: baz} = {bar: 1}); // Success

Like arrays, deconstruction can also be used for objects with nested structures.

let obj = {
  p: [
    'Hello',
    { y: 'World' }
  ]
};

let { p: [x, { y }] } = obj;
x // "Hello"
y // "World"
Note that p is a pattern, not a variable, and therefore will not be assigned.
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
In the above code, only line is a variable, loc and start are schemas and will not be assigned.

Examples of nested assignments:

let obj = {};
let arr = [];

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

obj // {prop:123}
arr /
Object deconstruction can also specify default values, which take effect only if the property value of the object is strictly equal to undefined.

var {x = 3} = {};
x // 3

var {x, y = 5} = {x: 1};
x // 1
y // 5

var {x:y = 3} = {};
y // 3

var {x:y = 3} = {x: 5};
y // 5

var { message: msg = 'Something went wrong' } = {};
msg // "Something went wrong"

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

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

//If the deconstruction fails, the value of the variable is equal to undefined.
let {foo} = {bar: 'baz'};
foo // undefined

//If the deconstruction pattern is a nested object and the parent property of the child object does not exist, an error will be reported.
// Report errors
let {foo: {bar}} = {baz: 'baz'};
Object deconstruction assignment can easily assign methods of existing objects to a variable.

let { log, sin, cos } = Math;
The above code assigns the logarithmic, sinusoidal and cosine methods of Math objects to the corresponding variables, which makes it much easier to use.

String deconstruction assignment

String deconstruction assignment is converted to an array-like object, which has a length attribute

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

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

Deconstruction Assignment of Numbers and Boolean Values

When deconstructing assignment, if the right side of the equal sign is a value and a Boolean value, it will first be turned into an object.

let {toString: s} = 123;
s === Number.prototype.toString // true
s//function toString() { [native code] }

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


Deconstruction and Assignment of Function Parameters

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]

Purpose:
(1) Values of exchange variables

let x = 1;
let y = 2;

[x, y] = [y, x];
(2) Return multiple values from a function

// Returns an array

function example() {
  return [1, 2, 3];
}
let [a, b, c] = example();

// Return an object

function example() {
  return {
    foo: 1,
    bar: 2
  };
}
let { foo, bar } = example();
(3) Definition of function parameters

// A parameter is a set of ordered values
function f([x, y, z]) { ... }
f([1, 2, 3]);

// A parameter is an unordered set of values
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});

(4) Extracting JSON data

Deconstruction assignment is especially useful for extracting data from JSON objects.

let jsonData = {
  id: 42,
  status: "OK",
  data: [867, 5309]
};

let { id, status, data: number } = jsonData;

console.log(id, status, number);
(5) Default values of function parameters

By specifying the default value of the parameter, you avoid rewriting var inside the function body foo = config.foo || 'default foo';

jQuery.ajax = function (url, {
  async = true,
  beforeSend = function () {},
  cache = true,
  complete = function () {},
  crossDomain = false,
  global = true,
  // ... more config
}) {
  // ... do stuff
};
(6) Traversing Map Structure
Any object deployed with the Iterator interface can be traversed in a for...of loop. Map structure supports Iterator interface naturally, and it is very convenient to obtain key names and key values with deconstruction assignment of variables.
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
If you only want to get the key name, or just want to get the key value, you can write as follows.
// Get key name
for (let [key] of map) {
  // ...
}

// Get key value
for (let [,value] of map) {
  // ...
}
(7) Method of specifying input module
When loading modules, you often need to specify which methods to input. Deconstruction assignment makes the input statement very clear.

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



  1. Reference link

Other

Posted by Arez on Mon, 01 Apr 2019 23:12:29 -0700