《三》ES6+ 中的解构赋值、展开运算符、逻辑赋值运算符

本文详细介绍了ES6中的解构赋值概念,包括数组和对象的解构方式,以及默认值的设定。同时,探讨了展开运算符在字符串、数组和对象中的应用,并介绍了ES12新增的逻辑赋值运算符。

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

解构赋值:

解构赋值是对赋值运算符的一种扩展。ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。

数组的解构赋值:

数组的解构赋值:左侧每个变量的值就等于右侧数组对应位置的值。

let arr = [1, 2, 3]
let [a, b, c] = arr

如果解构不成功,变量的值就等于undefined。

let [foo] = []

不完全解构,即等号左边的模式,只匹配一部分等号右边的数组,解构依然可以成功。

let [a, [b], d] = [1, [2, 3], 4]
a // 1
b // 2
d // 4

可以跳过数组的某个位置进行解构。

let arr = [1, 2, 3]
let [a,,b] = arr
a // 1
b // 3

事实上,只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。但是如果等号的右边不是可遍历的结构,那么将会报错。

// 报错。因为前五个表达式右边的值,转为对象以后不具备 Iterator 接口;最后一个表达式本身就不具备 Iterator 接口
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};
默认值:

解构赋值允许指定默认值。ES6 内部使用严格相等运算符判断一个位置是否有值,只有当一个数组成员严格等于 undefined,默认值才会生效。

let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'

如果默认值是一个表达式,那么这个表达式是惰性求值的,即只有在用到的时候,才会求值。

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

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

默认值可以引用解构赋值的其他变量,但该变量必须已经声明。

let [x = 1, y = x] = [];     // x=1; y=1
let [x = y, y = 1] = [];     // ReferenceError: y is not defined

对象的解构赋值:

对象的解构与数组的解构有一个重要的不同:数组的元素是有次序的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

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

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

如果解构失败,变量的值等于 undefined。

let {foo} = {bar: 'baz'};
foo // undefined

如果变量名与属性名不一致,必须写成下面这样。

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

 // 这实际上说明,对象的解构赋值是下面形式的简写:
let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' };
默认值:

对象的解构也可以指定默认值。默认值生效的条件是,对象的属性值严格等于 undefined。

var {x = 3} = {};
x // 3

var {x: y = 3} = {x: 5};
y // 5

var {x = 3} = {x: undefined};
x // 3

var {x = 3} = {x: null};
x // null
嵌套对象的解构赋值:
const obj = {
	family: {
		monther: 'Mary',
		father: 'Lee',
	},
}

// 此时 family 是模式,而不是变量,不会被赋值。
// 如果也想访问到 family 变量,可以写成:const {family, family: {monther, father}} = obj
const {family: {monther, father}} = obj
console.log(monther)
console.log(father)

其他类型的解构赋值:

解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。

字符串的解构赋值:

字符串也可以解构赋值。这是因为此时字符串被转换成了一个类似于数组的对象。

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
数值和布尔值的解构赋值:

解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。

// 数值和布尔值的包装对象都有 toString 属性,因此变量 s 都能取到值。
let {toString: s} = 123
console.log(s === Number.prototype.toString) // true

let {toString: s} = true
console.log(s === Boolean.prototype.toString) // true
null 和 undefined 的解构赋值:

由于 undefined 和 null 无法转为对象,所以对它们进行解构赋值,都会报错。

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

展开运算符:

展开运算符是三个点 ...,可以用来将字符串、数组在语法层面展开,也可以用来将对象按 key: value 的形式展开。

字符串的展开运算符:

展开运算符可以用来展开一个字符串。

const str = 'hello'
console.log(...str) // h e l l 0

数组的展开运算符:

展开运算符可以用来展开一个数组。

const arr1 = [1,3,5,7,9]
const arr2 = [2,4,6,8,10]

//  展开数组
console.log(...arr1) // 1 3 5 7 9

// 连接数组
const arr3 = [...arr1,...arr2] 

// 将类数组转为真正的数组
const divs = document.querySelectoreAll('div')
const divArr = [...divs]

对象的展开运算符:

ES9 开始支持对象使用展开运算符。只能用于在构建对象字面量时,将对象按 key: value 的形式展开。

let person1 = {name: 'Lee', age: 18}
consoloe.log(...person) // 报错

// 复制对象:等同于使用 Object.assign() 方法,是浅拷贝
let person2 = {...person1}
console.log(person2)

// 合并对象:等同于使用 Object.assign() 方法,是浅拷贝
let person3 = {...person1,  address: '广州'}
console.log(person3)

如果对象的展开运算符后面是一个空对象,则没有任何效果。

{...{}, a: 1} // { a: 1 }

如果对象的展开运算符后面不是对象,则会自动将其转换为对象。如果对象的展开运算符后面是字符串,它会自动转成一个类似数组的对象,因此返回的不是空对象。如果对象的展开运算符后面是数值、布尔值、null、undefined,由于转成的对象没有自身属性,所以返回一个空对象。

{...'hello'} // {0: "h", 1: "e", 2: "l", 3: "l", 4: "o"}

// 等同于 {...Object(1)}
{...1} // {}

// 等同于 {...Object(true)}
{...true} // {}

// 等同于 {...Object(undefined)}
{...undefined} // {}

// 等同于 {...Object(null)}
{...null} // {}

// 由于数组是特殊的对象,所以对象的扩展运算符也可以用于数组
{ ...['a', 'b', 'c'] } // {0: "a", 1: "b", 2: "c"}

逻辑赋值运算符:

ES12 中新增了逻辑赋值运算符,有: ||=&&=

// 逻辑或的赋值运算符
function fn(message) {
	message ||= '默认值' // 就相当于 message = message || '默认值'
	console.log(message)
}
fn()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值