数组解耦赋值
解耦赋值是什么
按照一定模式从数组或对象中提取值,对变量进行赋值。这种赋值方式被称为“解耦赋值”(Destructuring)
变量的解耦赋值–从指定的数组或对象中提取值,为指定变量进行赋值
语法结构:var/let[变量名称1,变量名称2,…]=数组或对象
let [a, b, c] = [1, 2, 3]
console.log(a, b, c) //1 2 3
"解耦赋值"本质上属于“模式匹配”。赋值运算符两边的模式相同,左边的变量会被赋予对应位置的值
解耦赋值失败
解耦赋值失败—定义变量的数量大于值的数量
如果解耦赋值失败的话,变量的值等于undefined。
如下代码示例:
变量的索引值应该对应值的索引值
目前的情况,定义了一个变量a,并没有对应的值,
这个时候相当于声明了一个变量a,但没有赋值(默认值为undefined)
let [a] = []
console.log(a); //undefined
let [m, n] = [1];
console.log(m, n) //1 undefined
如果不想解耦赋值失败的话–定义变量的数量与值的数量保持一致
不完全解耦赋值
如果赋值运算符左边的变量的模式只匹配赋值运算符右边数组的一部分的话,则会解耦赋值不完全。但这种情况下,解耦赋值依旧可以成功。
//不完全解耦赋值 -- 定义变量的数量小于值的数量
let [a, b] = [1, 2, 3]
console.log(a, b) //1 2
默认值
解耦赋值失败时,变量的默认值为undefined
默认值–指的是在解耦赋值失败时,重写undefined默认值
let [a = true] = []
console.log(a) //true
let [x, y = 100] = [10]
console.log(x, y) //10 100
值得注意的是:ES6底层将为变量赋值的值与undefined进行比较(全等于),指定的默认值生效。如:
let [m, n = 100] = [10, undefined]
console.log(m, n) //10 100
对象的解耦赋值
什么是对象的解耦赋值
- 从对象中提取值,为变量进行赋值
- 变量名称必须与对象的属性名称一一对应
- 如果不对应,导致解耦赋值失败
如以下代码:
let { x, y } = {
x: 10,
y: 20
}
console.log(x, y) //10 20
let [a, b] = [1, 2]
console.log(a, b) // 1 2
解耦赋值他的赋值运算符的两边格式保持一致,如果不一致的话就会报错。
let [m, n] = {
m: 10,
n: 20
}
console.log(m, n) //报错,结构不一致
解耦赋值不仅仅只能赋值普通的值,还能赋值函数
let { m, n } = {
m: 100,
n: function() {
return 10;
}
}
console.log(n) //[Function: n]
console.log(n()) //10
let [m, n] = [100, function() { return 10; }]
console.log(n()) //10
我们还可以这样写
let { m, n } = {
m: {
name: '张无忌'
},
n: function() {
return 10;
}
}
console.log(m) //{ name: '张无忌' }
console.log(m.name) //张无忌
解耦赋值扩展
解耦赋值:定义变量的结构与数组或对象的结构保持一致
- 数组的解耦赋值: 变量的索引值与值的索引值保持一致
- 对象的解耦赋值: 变量的名称与对象属性的名称保持一致
数组的解耦赋值:
let [[a, b], c] = [[1, 2], 3]
console.log(a, b, c) //1 2 3
对象的解耦赋值:
let { m: { name, age }, n } = {
m: {
name: '张无忌',
age: 18
},
n: 10
}
console.log(name, age)
字符串的解耦赋值
字符串的解耦赋值变量的数量与字符串中字符的数量进行对应
let [a, b, c] = "xxyyzz"
console.log(a, b, c) //x x y
将中文汉字作为一个字符来看待,也可以。语法结构支持,但实际开发很少见
let [a, b, c] = '大前端'
console.log(a, b, c)
数值与布尔值的解耦赋值
数字值的解耦赋值如果作为值的是一个数字值,那么他的结果就是报错,因为数字值是不能被迭代遍历的。
解耦赋值作为值的类型必须是可迭代遍历的
let [a] = 100
console.log(a) //100 is not iterable 他是不可迭代的
我们定义个Number类型的对象,可以使用他的toString()方法输出字符串
let num = new Number(100)
console.log(typeof num.toString()); //string
解耦赋值时,如果赋值运算符右边是数值或布尔值的话,则会先转为对象.
let { toString: m } = 100
console.log(m === Number.prototype.toString); //true
具体理解如下图:
布尔值也不能直接解耦赋值,和数字值一样,要想解耦赋值,先将数字值和布尔值转换成对象类型
let [a] = true
console.log(a)//报错
和数字值一样,要想解耦赋值,先将数字值和布尔值转换成对象类型
let { toString: x } = true;
console.log(x === Boolean.prototype.toString) //true
函数参数的解耦赋值
函数定义- - -形参:相当于在函数作用域中定义了一个局部变量(没有赋值)
function fn(a, b) {
console.log(a, b) //10 20
}
函数调用 —实参,相当于在函数作用域中定义的变量进行赋值
fn(10, 20)
1.数组形式参数的解耦赋值
function f([a, b]) {
console.log(a, b) //10 20
}
f([10, 20])
2.对象形式参数的解耦赋值
function f({ m, n }) {
console.log(m, n) //10 20
}
f({
m: 10,
n: 20
})
解耦赋值的用途
1.交互变量的值
当我们进行交换变量的值,可能会这么写
//1.交换变量的值
let x = 1, y = 2;
let w = x;
x = y
y = w;
console.log(x, y) //2 1
我们用解耦赋值的方式写
let x=1,y=2;
[x, y] = [y, x]
console.log(x, y) //2 1
2.从函数中返回多个值
我们想要函数中返回多个值时,首先要声明函数,然后赋值,最后得解析
function fn() {
return [1, 2, 3]
}
var arr = fn()
console.log(arr[0], arr[1], arr[2]) //1 2 3
可以看到很麻烦,但是用解耦赋值就方便了很多
function fn() {
return [1, 2, 3]
}
let [a, b, c] = fn()
console.log(a, b, c)
3.函数参数的定义
function f([a, b, c = 0]) {
console.log(a, b, c)
}
f([1, 2]) // 1 2 0
4.提取JSON格式的数据内容
使用解耦赋值可以快捷简便的获取到JSON的数据内容
let Data = {
name: '林俊杰',
address: '新加坡',
work: '歌手'
}
let { name, address, work } = Data
console.log(name, address, work) //林俊杰 新加坡 歌手