把解构想成"拆快递":数组解构 [ ] 是按箱子里的位置拿——第一个格子拿第一个,第二个格子拿第二个;对象解构 { } 是按快递面单上的名字拿——单子上写着 name 就拿 name。以前要 arr[0]、obj.name 一个一个取,现在一行拆出来。
数组就是一排格子,[ ] 里写几个变量,就按从左到右的位置一一对应拿出来。
// 以前:一个格子一个格子取下标 let arr = ["大哥", "二哥", "三哥"]; // 一排格子,第0、1、2格 let a = arr[0]; // 第 0 格 let b = arr[1]; // 第 1 格 let c = arr[2]; // 第 2 格 // 现在:一行按位置拆 let [a, b, c] = ["大哥", "二哥", "三哥"]; // 把数组拆成三个小盒子分别接住 // ↑ ↑ ↑ ↑ ↑ ↑ // 第1格 第2格 第3格 console.log(a, b, c); // 大哥 二哥 三哥
对象是"贴了名字的柜子",{ } 里写的变量名必须和属性名一模一样,JS 才能对着名字开门。
// 以前:obj.name、obj.age 一个个取
let obj = { name: "大喇叭", age: 22 }; // 一个对象,贴了 name 和 age
let n = obj.name; // 手动按名字取(name 是字符串,不加括号)
let age = obj.age; // 再取另一个
// 现在:{ } 里写属性名,变量名必须和属性名一致
let { name, age } = { name: "大喇叭", age: 22 }; // 按名字拆快递:名字对上就把值抠出来
// ↑ ↑ ↑ ↑
// 要 name 要 age 源对象里有 name 和 age
console.log(name, age); // 大喇叭 22
如果你想把属性 name 取出来却想叫它别的名字(比如叫 myName),不能直接写 { myName },那样会去找不存在的 myName 属性。要写 { name: myName }——冒号左边是源对象里的名字,右边是你想叫的新名字。
拆快递时某个格子空着,就自动放上"备用件"。
// 以前:三目运算符判断 let arr = ["大哥", "二哥"]; // 只有前两格 let c = arr[2] === undefined ? "默认值" : arr[2]; // 第3格空着就用默认值 // 现在:在 [ ] 里直接写 = 默认值 let [a, b, c = "默认值"] = ["大哥", "二哥"]; // 第3格空着,自动用"默认值" // ↑ 第 3 格是空的,自动用默认值 console.log(c); // 默认值
默认值只在"取不到(undefined)"时触发。如果你传过去的是 0、""、false,这些都是"客人真放进去的东西",不会触发默认值——这点和 || 兜底完全不同。
以前交换两个数要开第三个"中转柜",现在一行搞定。
// 以前:必须开个临时变量 temp let a = 1, b = 2; // 两个变量 let temp = a; // 先把 a 放进 temp a = b; // a 换成 b b = temp; // b 换成 temp 里的原值 // 现在:一行解构交换 let a = 1, b = 2; // 重新声明两个变量 [a, b] = [b, a]; // 右边先把 [2,1] 打包,再拆给左边 console.log(a, b); // 2 1
接口返回一个对象,以前函数里得 user.name、user.age 写半天;现在参数直接 { } 拆开,用哪个取哪个。
// 以前:参数是整个对象,进去再 . 出来
function show(user) { // 收整个对象
console.log(user.name + " " + user.age); // 手动 . 出来
}
// 现在:参数直接解构,名字对上就自动拆开
function show({ name, age }) { // 传进来的对象自动按名字拆成 name、age
// ↑ 传进来的是 {name:'大喇叭', age:22}
console.log(name + " " + age); // 直接用拆出来的变量
}
show({ name: "大喇叭", age: 22 }); // 大喇叭 22
配合默认值最实用:function show({ name = "未知", age = 0 } = {})——= {} 是连对象都没传时兜底,name = "未知" 是对象里没这字段时兜底。接口偶尔少返回字段时,这么写不会崩。
① 可能在什么地方用:接收接口返回值(let { data, code } = res)、React/Vue 组件 props 解构、函数传配置对象、交换变量、从数组里取前几个元素。
② 常见的问题:对象解构变量名和属性名对不上拿到 undefined;解构整个对象参数时漏写 = {},不传对象就报"Cannot read property of undefined";想改名却忘了写冒号语法。
③ 解决思路:对象解构前先 console.log 源对象确认字段名;函数参数一律写 function fn({ a = 1 } = {});要改名就用 { 原名: 新名 };数组解构跳位置用空位逗号,如 [, , third] = arr。