导航


HTML

CSS

JavaScript

浏览器 & 网络

版本管理

框架

构建工具

TypeScript

性能优化

软实力

算法

UI、组件库

Node

冷门技能

数组解构 - 模式匹配(结构化赋值)

let [a, b, c] = [1, 2, 3];
console.log(a, b, c);
// 1 2 3

let [d, [e], [f]] = [1, [2], [3]];

let [a, [b, c], [d, [e, f, [g]]]] = [1, [2, 3], [4, [5, 6, [7]]]];
console.log(a, b, c, d, e, f, g);
// 1 2 3 4 5 6 7

⭐️ 解构失败 - undefined 填充

let [a, [b, c], [d, [e, f, [g]]]] = [1, [2, ], [, [, 6, [7]]]];
console.log(a, b, c, d, e, f, g);

// 1 2 undefined undefined undefined 6 7

不完全解构

let [a, [b, ], [, [e, , [g]]]] = [1, [2, 3], [4, [5, 6, [7]]]];
console.log(a, b, e, g);

// 1 2 5 7

解构默认值

// 默认值给3
let [a = 3] = [1];

let [b = 3] = []; // b = 3

let [a, b = 2] = [1]; // a = 1, b = 2

undefined 会被看做没有值,null 则不然

// undefined 会被认为没有传值
let [a, b = 2] = [1, undefined]; // a = 1, b = 2

let [a, b = 2] = [1, null]; // a = 1, b = null
function test() {
	console.log('test--', 10);
}

let [x = test()] = [1];

console.log('x--', x);

// 打印 'x-- 1'

let [y = test()] = [];

console.log('y--', y);

// 打印 test-- 10
// 接着打印 y-- undefined,因为 undefined 是函数的默认返回值
let [x = 1, y = x] = [];
console.log(x, y);

// 1 1
let x = 10;
let [x = 1, y = x] = [];

// 两次声明了x:Identifier 'x' has already been declared
let [x = 1, y = x] = [2];
console.log(x, y); // 2 2
let [x = 1, y = x] = [1, 2];
console.log(x, y); // 1 2
let [x = y, y = 1] = [];
console.log(x, y);
// 暂时性死区报错:
// Cannot access 'y' before initialization

数组也是特殊的对象,也可以进行解构赋值

let arr = [1, 2, 3];
let { 0: first, [arr.length - 1]: last } = arr;
console.log(first, last);

// 1 3

⭐️ 对象解构

let { a: a, b: b, c: c } = { a: 1, b: 2, c: 3 };
console.log(a, b, c); // 1 2 3

let { a, b, c } = { a: 1, b: 2, c: 3 };
console.log(a, b, c); // 1 2 3

不完全解构

let { a, b, c } = { a: 1, b: 2, c: 3, e: 4 };
console.log(a, b, c); // 1 2 3

let { a = 2, b, c } = { b: 2, c: 3, e: 4 };
console.log(a, b, c); // 2 2 3

解构失败

let { a, b, c, d, e, f } = { a: 1, b: 2, c: 3, e: 4 };
console.log(a, b, c, d, e, f);
// 1 2 3 undefined 4 undefined

对象解构没有顺序

let { a, b, c, e } = { c: 3, e: 4, a: 1, b: 2 };
console.log(a, b, c, e); // 1 2 3 4

⭐️ 起别名 - 要匹配的属性名: 要使用的变量名称

const person = [
  {
    name: 'Lance',
    age: 26
  },
  {
    name: 'GC',
    age: 31
  },
  {
    name: 'Sherry',
    age: 30
  }
]

const [ { name: name1 }, { name : name2 } ] = person;
console.log(name1, name2);

⭐️ 嵌套解构

var person = {
	name: 'hh',
  son: {
  	name: 'bb',
    son: {
    	name: 'cc',
    }
  }
}

let { son: { son } } = person;

console.log(son); // { name: 'cc' }

// 为了没有歧义,起别名方式取值
let { son: { son: grandson } } = person;

console.log(grandson); // { name: 'cc' }
let { a: {c} } = {
  a: {
    c: 4
  }
}
console.log(a); // ReferenceError: a is not defined
// ⭐️ 没有用a,a的作用只是用来解构里边的c,所以a is not defined

计算属性解构

let a = 'x', b = 'y', obj = {};
( { a: obj[a + b] } = { a: 2 } ); // 必须得外层加括号,不然会当做代码块报错
console.log(obj); // { xy: 2 }
let obj1 = { a: 1, b: 2, c: 3 }, obj2 = {};
({ a: obj2.x, b: obj2.y, c: obj2.z } = obj1);
console.log(obj2); // { x: 1, y: 2, z: 3 }

⭐️ 变量的解构,就是变量的赋值,所以叫变量解构赋值

let a = 10, b = 20;
[b, a] = [a, b];
console.log(a, b); // 20 10

模式匹配,可以匹配同源属性(同一个源属性)

let { a: x, a: y } = { a: 1 };
// a:x a是要在=后面对象中匹配的key,x才是变量本身
console.log(x, y); // 1 1
var x = 200,
    y = 300,
    z = 100;
var obj1 = {
	x: {y: 42},
  z: {y: z}
};

({y: x = {y: y}} = obj1);
// 1. 首先在obj1中找有没有y属性,发现没有
// 2. 那么此刻y就取了后边x的默认值{y: y}
// 3. 在 x 的默认值 {y: y} 中,第二个y才是变量,第一个y是x下的属性
// 4. y变量在全局中找到了是300
// 5. x = {y: 300}

({z: y = {y: z}} = obj1);
// 1. 在 obj1 中解构z,发现obj1中有z
// 2. 那么此时z就不会取y的默认值{y:z},而是直接找y
// 3. 所以 y = {y: z}
// 4. 又因为z=100
// 5. 所以 y = {y: 100}

({x: z = {y: x}} = obj1);
// 1. 在obj1中能找到x
// 2. 那么不把z赋值为{y: x}
// 3. 而是z = {y: 42}

console.log(x.y, y.y, z.y); // 300 100 42

函数参数的解构

function test([x, y]) {
	console.log(x, y);
}
test([1, 2]); // 1 2
test([1]); // 1 undefined
test([]); // undefined undefined
function foo({x, y}) {
	console.log(x, y);
}
foo({x: 1, y: 2}) // 1 2
foo({x: 1}) // 1 undefined
foo({}) // undefined undefined
function foo({x = 10} = {}, {y} = {y: 10}){
	console.log(x, y);
}
foo(); // 10 10
foo({}, {}) // 10 undefined
foo({x: 2}, {y: 3}) // 2 3

理解简写形式

({x = 10} = {});
console.log(x); // 10

({y} = {y: 10});
console.log(y); // 10

({x = 10} = {});应该理解为
({x: x = 10} = {})

({y} = {y: 10});应该理解为
({y: y} = {y: 10})

解构的隐式转换

const [a, b, c, d, e] = 'hello';
console.log(a, b, c, d, e); // h e l l o

let {length: len} = 'hello';
console.log(len); // 5

boolean、string、number 都能进行隐式转换

let {toString: s} = 123;
console.log(s); //  toString() { [native code] }

console.log(s === Number.prototype.toString); // true

undefined, null 不能隐式转换

let { prop } = undefined;
let { prop } = null;

// Uncaught TypeError: 
// Cannot destructure property 'prop' of 'undefined'
// as it is undefined.