解构赋值是JavaScript中直接从数组或对象提取值的底层能力:数组解构按位置匹配,支持跳过、默认值和剩余操作符;对象解构按属性名匹配,支持重命名、嵌套和默认值;字符串、Map等可迭代对象也可解构;函数参数解构需防null/undefined。
解构赋值不是语法糖,而是 JavaScript 中真正改变变量提取方式的底层能力——它让你跳过点号、下标和重复声明,直接从数组或对象里“拎出”需要的值。
数组解构靠的是顺序匹配,左边方括号 [] 里的变量位置,严格对应右边数组索引。它不修改原数组,只做一次性提取。
const [x, y] = [100, 200]; // x = 100, y = 200
const [first, , , fourth] = ['a', 'b', 'c', 'd']; // first = 'a', fourth = 'd'
undefined 时生效(null、0、false 都不会触发)const [a = 1, b = 2] = [undefined, 0]; // a = 1, b = 0
... 操作符捕获剩余所有元素const [head, ...tail] = [1, 2, 3, 4]; // head = 1, tail = [2, 3, 4]
⚠️ 注意:如果右边不是可遍历对象(如 null 或 undefined),会直接报 TypeError: Cannot destructure property 'x' of 'y' as it is undefined.
对象解构靠的是属性名,不是位置。左边花括号 {} 中的标识符必须与右边对象的键名一致,否则得到 undefined;想换个变量名?用 旧名: 新名 语法。
const { name, age } = { name: 'Alice', age: 30 }; // name = 'Alice', age = 30const { name: fullName, age: years } = { name: 'Bob', age: 25 }; // fullName = 'Bob', years = 25const { user: { profile: { avatar } } } = { user: { profile: { avatar: 'url.jpg' } } }; // avatar = 'url.jpg'const { title = 'Untitled', tags = [] } = {}; // titl
e = 'Untitled', tags = []⚠️ 常见坑:不能直接对未声明变量解构,比如 { x } = obj 会报语法错误;必须写成 const { x } = obj 或 let { x }; ({ x } = obj)(加括号绕过解析歧义)。
字符串在解构时被当作类数组处理(实现了 Symbol.iterator),所以能用数组解构语法逐字符提取,还能拿到 length 属性。
const [a, b, c] = 'hey'; // a = 'h', b = 'e', c = 'y'
const { 0: first, 2: third, length } = 'hello'; // first = 'h', third = 'l', length = 5这说明解构的目标不限于 Array 或 Object,只要可迭代(iterable)或有属性访问能力,就能参与解构——比如 Map、Set,甚至自定义对象。
把解构直接写进函数形参,是高频且实用的场景,尤其适合配置对象传参。
function draw({ x = 0, y = 0, color = 'black' }) { console.log(x, y, color); }draw({ x: 10, y: 20 }); // 10 20 'black'function connect({ host, port, timeout = 5000, retry: { max = 3 } }) { /* ... */ }connect({ host: 'api.example.com', port: 8080, retry: { max: 5 } });undefined 或 null,整个解构会失败,报错;务必加防御,比如function safe({ a = 1 } = {}) { return a; } // 默认空对象兜底最易被忽略的一点:解构默认值的求值时机是「运行时」,不是定义时——这意味着你可以写 a = expensiveCalc(),它只在需要时才执行。