ES6学习之<解构赋值>

本文详细介绍了JavaScript中的解构赋值语法,包括数组、对象、字符串、数值和布尔值等多种类型的解构,以及在函数参数、默认值、圆括号使用等方面的应用。解构赋值提供了一种高效的方式来交换变量值、提取复杂结构中的数据,以及在函数参数中设置默认值。此外,文章还展示了如何在不同场景下正确和错误地使用圆括号。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解构赋值

允许按照一定模式从数组和对象中提取值,然后对变量进行赋值

  • 数组解构赋值
// 完全解构
let [foo, [[bar], baz]] = [1, [[2], 3]] // foo: 1; bar: 2; baz: 3
let [x, , y] = [1, 2, 3] // x: 1; y: 3
let [x, y, ...z] = ['a'] // x: "a"; y: undefined; z: []

// 不完全解构
let [x, y] = [1, 2, 3] // x: 1; y: 2

// 解构不成功,变量值为undefined
let [foo] = [] // foo: undefined

// 右边是不可遍历的结构,则报错
let [foo] = 1  // error, 转为对象以后不具备Iterator接口
let [foo] = {} // error, 本身不具备Iterator接口

// Set结构可以使用数组形式解构赋值
let [x, y, z] = new Set(['a', 'b', 'c']) // x: "A"

// 只要具有Iterator接口,就可以采用数组形式解构赋值
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() // sixth 5

// 默认值, ES6内部使用严格相等(===)运算符判断一个位置是否有值
let [foo = true] = [] // foo
let [x = 1] = [undefined] // x: undefined
let [x = 1] = [null]  // x: null
// 默认值是一个表达式, 则表达式是惰性求值的, 即只有用到时才会求值
function f() { return 'aaa' }
let [x = f()] = [] // x = "aaa"
// 默认值可以引用解构赋值的其他变量,但该变量必须已经声明
let [x = 1, y = x] = [] // x = 1; y = 1
let [x = y, y = 1] = [] // error
  • 对象解构赋值
// 对象的属性没有次序,变量必须与属性同名才能取到正确的值
let { bar, foo, baz } = { foo: 1, bar: 2, tmp: 3 } // bar: 2; foo: 1; baz: undefined
let { bar: baz } = { bar: 1 } // bar: error; baz: 1

// 嵌套结构解构
let { p, p: [x, { y }] } = { p: ['hello', { y: 'world' }] } 
// p: [ 'hello', { y: 'world' } ]; x: 'hello'; y: 'world'

// 嵌套赋值
let obj = {}, arr = [];
({ foo: obj.prop, bar: arr[0] } = { foo: 123, bar: true });
// obj: { prop: 123 }; foo: [ true ]

// 对象默认值,生效条件:对象的属性值严格等于undefined
let { x = 1, y: z = 2 } = {}  // x: 1; z: 2
let { x = 3 } = { x: undefined } // x: 3
let { x = 3 } = { x: null }   // x: null

// 已声明变量用于解构赋值
let x;
{ x } = { x: 1 } // error
({ x } = { x: 1 }) // x: 1

// 数组本质是特殊的对象
let arr = [1, 2, 3]
let { 0: first, [arr.length - 1]: last } = arr // first: 1; last: 3
  • 字符串解构赋值
const [a, b, c, d, e] = 'hello' // a: "h"; b: "e"; c: "l"; d: "l"; e: "o"
let { length: len } = 'hello'   // len: 5
  • 数值和布尔值解构赋值
// 若等号右边值不是对象或数组,则先转为对象
// 数值解构赋值
let { toString: s } = 123
s === Number.prototype.toString // true

// 布尔值解构赋值
let { toString: s } = true
console.log(s === Boolean.prototype.toString) // true

// 若等号右边值无法转为对象, 则报错
let { prop: x } = undefined  // error
let { prop: x } = null			 // error
  • 函数参数解构赋值
function move({ x = 0, y = 0 } = {}) { return [x, y] }
move({ x: 3 }) // [3, 0]
move({})			 // [0, 0]
move()				 // [0, 0]

function move({ x, y } = { x: 0, y: 0 }) { return [x, y] }
move({ x: 3 }) // [3, undefined]
move({})			 // [ undefined, undefined ]
move()				 // [0, 0]

[1, undefined, 3].map((x = 'yes') => x) // [ 1, 'yes', 3 ]
  • 圆括号问题
// 不能使用圆括号的情况
// 1.变量声明语句
let [(a)] = [1] // error
let { x: (c) } = {} // error
let ({ x: c }) = {} // error
let { (x: c) } = {} // error
let { (x): c } = {} // error
let { o: ({ p: p }) } = { o: { p: 2 } } // error
// 2.函数参数也属于变量声明
function f([(z)]) { return z; }			// error
function f([z, (x)]) { return x; }	// error
// 3.赋值语句的模式
({ p: a }) = { p: 42 } // error
([a]) = [5]  // error
[({ p: a }), { x: c }] = [{}, {}] // error

// 可以使用圆括号的情况
// 唯一:<<赋值语句>>的<<非模块式>>部分可以使用圆括号
[(b)] = [3]   		// b: 3
({ p: (d) } = {}) // d: undefined
[(parseInt.prop)] = [3] // parseInt.prop: 3
  • 解构赋值用途
// 1.交换变量的值
let x = 1, y = 2;
[x, y] = [y, x]  // x: 2; y: 1
// 2.从函数返回多个值
function example() { return [1, 2, 3] } // 返回一个数组
let [a, b, c] = example()		 // a: 1; b: 2; c: 3
function example() { return { foo: 1, bar: 2 } } // 返回一个对象
let { foo, bar } = example() // foo: 1; bar: 2
// 3.函数参数的定义
function f([x, y, z]) { console.log(x, y, z) }  // x: 1; y: 2; z: 3
f([1, 2, 3]) // 有次序的值
function f({x, y, z}) { console.log(x, y, z) }  // x: 1; y: 2; z: 3
f({ z: 3, y: 2, x: 1 }) // 无次序的值
// 4.提取JSON数据
let jsonData = { id: 1, status: 200 }
let { id, status } = jsonData   // id: 1; status: 200
// 5.函数参数的默认值
function(x, { y = 1, z = function() {} }) {}
// 6.遍历Map结构
for (let [key, val] of map) {}  // 获取键值
for (let [key] of map) {}				// 获取键
for (let [, val] of map) {}			// 获取值
// 7.获取外部模块的指定内容
import React, { Component, Fragment } from 'react'
const { SourceNode } = require("source-map")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值