【03】ES6: Destructuring assignment

1. Destructuring and assignment of arrays

ES6 allows you to extract values ​​from arrays and objects and assign values ​​to variables according to certain patterns, which is called destructuring.

1. Basic use

Following "pattern matching", assignment is completed if the index value is the same

// 为变量赋值,只能直接指定值。
let a = 1
let b = 2
let c = 3

// 解构赋值:从数组中提取值,按照对应位置,对变量赋值。
let [a, b, c] = [1, 2, 3]
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 // []

2.Default value

(1) Basic usage of default values

const [a, b] = []
console.log(a, b) // undefined undefined

const [a = 1, b = 2] = []
console.log(a, b)    // 1 2

(2) Effective conditions for default values

ES6 uses the strict equality operator (===) internally to determine whether a position has a value. Therefore, the default value will only take effect if an array member is strictly equal to undefined.

const [a = 1, b = 2] = [3, 0] // 3 0
const [a = 1, b = 2] = [3, null] // 3 null
const [a = 1, b = 2] = [3] // 3 2

const [x = 1] = [undefined] // 1
const [x = 1] = [null] // null

(3)Default value expression

If the default value is an expression, then the expression is lazily evaluated, that is, it will only be evaluated when it is used.

// x 能取到值,所以函数 f 根本不会执行
function f() {
    
    
	console.log('aaa')
}

let [x = f()] = [1]

(4)Default value reference

The default value can refer to other variables assigned by destructuring, but the variable must have been declared.

let [x = 1, y = x] = [] // 1 1
let [x = 1, y = x] = [2] // 2 2
let [x = 1, y = x] = [1, 2] // 1 2
let [x = y, y = 1] = [] // ReferenceError: Cannot access 'y' before initialization (x 用 y 做默认值时,y 还没有声明)

3. Application of array destructuring and assignment

(1) Array-like object arguments

function func() {
    
    
	const [a, b] = arguments
    console.log(a, b)    // 1 2
}
func(1, 2)

(2)NodeList

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>NodeList</title>
</head>
<body>
<p>1</p>
<p>2</p>
<p>3</p>
<script>
    const [p1, p2, p3] = document.querySelectorAll('p')
    console.log(p1, p2, p3)
    /*
    <p>1</p>
    <p>2</p>
    <p>3</p>
    */
</script>
</body>
</html>

(3) Destructuring assignment of function parameters

const array = [1, 1]
// const add = arr => arr[0] + arr[1]
const add = ([x = 0, y = 0]) => x + y
console.log(add(array)) // 2
console.log(add([])) // 0
[[1, 2], [3, 4]].map(([a, b]) => a + b)
// [ 3, 7 ]

(4) Exchange the value of the variable

let x = 2, y = 1

// 原来
let tmp = x
x = y
y = tmp

// 现在
[x, y] = [y, x] // [x, y] = [1, 2]
console.log(x, y) // 1 2

(5) Skip a certain value and separate it with commas

When destructuring an array, you can ignore values ​​that do not need to be destructured. You can use commas to ignore the destructured array, so that you do not need to declare more variables to store values:

var [a, , , b] = [10, 20, 30, 40]
console.log(a) // 10
console.log(b) // 40

(6) Use in remaining parameters

Normally, we need to treat the remaining array items as a separate array. At this time, we can use the expansion syntax to treat the values ​​in the remaining array as a separate array, as follows:

var [a, b, ...rest] = [10, 20, 30, 40, 50]
console.log(a) // 10
console.log(b) // 20
console.log(rest) // [30, 40, 50]

There cannot be a comma after rest, otherwise an error will be reported, and the program will recognize that there is a value after you. ...rest is the destructuring of the remaining parameters, so it can only be placed at the end of the array. There cannot be any variables after it, otherwise an error will be reported.

2. Destructuring and assigning objects

1. Basic use

The destructuring of objects is basically similar to that of arrays. The variables of object destructuring are defined in {}.

Following "pattern matching", assignment of attributes with the same name is completed.

// 对象没有索引,但对象有更明确的键,通过键可以很方便地去对象中取值
let {
    
     foo, bar } = {
    
     foo: 'aaa', bar: 'bbb' }
foo // 'aaa'
bar // 'bbb'

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

If the variable name is inconsistent with the attribute name, it must be written as follows.

// foo 是匹配的模式,baz 才是变量。真正被赋值的是变量 baz,而不是模式 foo。
let {
    
     foo: baz } = {
    
     foo: 'aaa', bar: 'bbb' }
baz // 'aaa'
foo // error: foo is not defined

2.Default value

The condition for the default value to take effect is that the object's property value is strictly equal to undefined.

If the default value is an expression, the default value expression is lazily evaluated.

var {
    
     a = 10, b = 5 } = {
    
     a: 3 } // a = 3, b = 5
var {
    
     a = 10, b = 5 } = {
    
     a: 3, b: undefined } // a = 3, b = 5
var {
    
     a = 10, b = 5 } = {
    
     a: 3, b: null } // a = 3, b = null

3. Application of object destructuring and assignment

(1) Object as function parameter

// 之前
const logPersonInfo = user => console.log(user.name, user.age)
logPersonInfo({
    
     name: 'jerry', age: 18 }) // jerry 18

// 之后
const logPersonInfo = ({
    
     age = 21, name = 'tom' }) => console.log(name, age);
logPersonInfo({
    
    name: 'jerry', age: 18}) // jerry 18
logPersonInfo({
    
    }) // tom 21

(2) Return multiple values ​​from a function

// 返回一个数组
function example() {
    
    
	return [1, 2, 3]
}
let [a, b, c] = example()

// 返回一个对象
function example() {
    
    
	return {
    
    
		foo: 1,
		bar: 2
	}
}
let {
    
     foo, bar } = example()

(3) Complex nesting (multiple destructuring assignments)

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

// 这时 p 是模式,不是变量,因此不会被赋值。
let {
    
     p: [x, {
    
     y }] } = obj
x // 'Hello'
y // 'World'

// p 作为变量赋值
let {
    
     p, p: [x, {
    
     y }] } = obj
x // 'Hello'
y // 'World'
p // ['Hello', {y: 'World'}]
const node = {
    
    
	loc: {
    
    
		start: {
    
    
			line: 1,
			column: 5
		}
	}
}
// 三次解构赋值,分别是对 loc、start、line 三个属性的解构赋值。
// 注意,最后一次对 line 属性的解构赋值之中,只有 line 是变量,loc 和 start 都是模式,不是变量.
let {
    
     loc, loc: {
    
     start }, loc: {
    
     start: {
    
     line }} } = node
line // 1
loc  // Object {start: Object}
start // Object {line: 1, column: 5}

(4) Use in remaining parameters

The remaining parameters can also be used in the destructuring of the object. The remaining attributes in the object that are not deconstructed are aggregated to generate a new object.

const {
    
     a, c, ...rest } = {
    
     a: 1, b: 2, c: 3, d: 4 }
console.log(a)     // 1
console.log(c)     // 3
console.log(rest)  // { b: 2, d: 4 }

4. Points to note

(1) If you want to use a declared variable for destructuring assignment, you must be very careful.

// 错误的写法
let x
{
    
     x } = {
    
     x: 1 }
// SyntaxError: syntax error

The above code will report an error because the JavaScript engine will understand {x} as a code block, resulting in a syntax error. This problem can only be solved by not writing the curly brace at the beginning of the line to prevent JavaScript from interpreting it as a block of code.

// 正确的写法
let x
({
    
     x } = {
    
     x: 1 })

The above code puts the entire destructuring assignment statement within a parentheses, and it can be executed correctly.

(2) Destructuring assignment allows no variable name to be placed in the pattern on the left side of the equal sign. Therefore, you can write very weird assignment expressions.

({
    
    } = [true, false])
({
    
    } = 'abc')
({
    
    } = [])

Although the above expression is meaningless, the syntax is legal and can be executed.

(3) Since arrays are essentially special objects, object attributes of arrays can be deconstructed.

let arr = [1, 2, 3]
let {
    
     0 : first, [arr.length - 1] : last } = arr
first // 1
last // 3

The above code performs object destructuring on the array. The corresponding value of the 0 key of the array arr is 1, [arr.length - 1] is the 2 key, and the corresponding value is 3.

3. Destructuring and assignment of strings

Strings can also be destructured and assigned. You can destructure and assign values ​​in the form of arrays or in the form of objects.

// 数组形式解构赋值
const [a, b, , , c] = 'hello'
console.log(a, b, c) // h e o

// 对象形式解构赋值
// 类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。
const {
    
     0: a, 1: b, 4: o, length : len } = 'hello'
console.log(a, b, o, len) // h e o 5

4. Destructuring assignment of numerical and Boolean values

Destructuring and assignment can only be done in the form of objects. (First automatically convert the value on the right side of the equal sign into an object)

// 转化后的对象里没有任何的属性(没有 123 这个属性,也没有 true 这个属性)和方法,
// 所有的属性和方法都在它的继承 __proto__ 中,比如 toString 方法就是继承来的。
new Number(123)
new Boolean(true)

// 里面的值只能是默认值,继承的方法倒是可以取到
const {
    
     a = 1, toString: s } = 123
console.log(a, s) // 1 [Function: toString]

// 里面的值只能是默认值,继承的方法倒是可以取到
const {
    
     b = 1, toString } = true;
console.log(b, toString) // 1 [Function: toString]

5. There is no destructuring assignment for undefined and null

The rule of destructuring assignment is that as long as the value on the right side of the equal sign is not an object or array, convert it to an object first. Since undefined and null cannot be converted into objects, destructuring and assigning them will result in an error.

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

Guess you like

Origin blog.csdn.net/weixin_45559449/article/details/134579983