在
ES6
中,我们经常使用到解构赋值
这个知识点,今天我们就来好好讲讲这一小部分
知识点。咱们争取这回一次性
讲明白。今天是元宵节,祝大家节日快乐,只有我自己还在无聊的码字。
给我点个赞吧,嘿嘿!!!
一、数组的解构赋值
ES6
允许我们对一个数组
或者是对象
从中进行取值
,然后在对变量
进行赋值
的这个操作叫做解构。
。
1.1 基本用法
-
在以前,我们是这样对变量进行赋值的
jslet a = 1; let b = 2; let c = 3;
-
然而在ES6中,我们可以书写成以下方式:
jslet [a, b, c] = [1, 2, 3] console.log(a, b, c); // 1 2 3
这种写法有一个专业术语,叫做模式匹配 。其实我更喜欢叫映射
(一一对应)。
-
还有嵌套结构的写法
jslet [a, [b, c], d] = ['JavaScript', ['Vue', 'React'], 'Node']; console.log(a, b, c, d); // JavaScript Vue React Node
-
如果我们想获取数组的某一个下标的值可以这样写:
jslet [, [, a], b] = ['JavaScript', ['Vue', 'React'], 'Node']; console.log(a, b); // React Node
-
通过
...
可以获取到剩余值
。jslet [a, ...b] = ['JavaScript', 'Vue', 'React', 'Node']; console.log(a); // JavaScript console.log(b); // ['Vue', 'React', 'Node']
-
如果解构不成功,首先不会
报错
,控制台会打印undefined
。jslet [a, b] = ['Javascript']; console.log(b); // undefined
-
解构也可以是不完全解构,不比如我们只用到数组的第一项。
jslet [a] = ['JavaScript', 'vue', 'Node']; console.log(a); // JavaScript
1.2 解构原理
-
我们来简单说一下,为什么数组和对象可以解构,根本原因是我们的对象有
Interator接口
。jslet web = ['JavaScript', 'Vue']; console.log(web.__proto__);
有了这个接口,我们还可以对数组或对象进行遍历。
拓展 :在ES6中Set
和Map
也是可以解构和遍历的。
1.3 设置默认值
-
解构允许我们设置一个默认值,当我们取不到值的时候就会显示默认值
jslet [first, second = 'iyongbao' ] = ['Daven']; console.log(first, second); // Daven iyongbao
-
注意 如果数组的某一项是
undefined
,那么也会启用默认值。而null
是正常赋值的。jslet [a, b = 'Vue', c] = ['JavaScript', undefined, null]; console.log(a, b, c); // JavaScript Vue null
-
这里我给大家出一道
面试题
,大家看看会打印什么?jslet [x = y, y = 1] = []; console.log(x, y); // ???
为什么会这样呢?欢迎评论区告诉我。
二、对象的解构赋值
2.1 基本用法
-
解构
不仅适用于数组
,也适用于对象
。但是二者有一个很明显的区别
。先把结论和说一下:数组是有序的
,而对象可以是无序的,因为对象是一个个键值对(key=>value)
。解构数组
变量的取值
由数组的位置
来决定,解构对象
需要变量名
和对象属性一致
才能取到正确的值。js// 第一种写法 // let { username, age } = { username: 'iyongbao', age: 26 }; // 第二种:顺序可以颠倒,但是值不会变 let { age, username, hobbys } = { username: 'iyongbao', age: 26, hobby: 'Vue' }; console.log(username, age, hobbys); // iyongbao 26 console.log(hobby); // undefined
-
如果我就想变量名和对象属性名不一样,也是可以操作的。
jslet { age: aaa } = { username: 'iyongbao', age: 26 }; console.log(aaa); // iyongbao console.log(age); // 报错:ReferenceError: age is not defined
-
和数组一样,对象也是支持嵌套解构的
jslet { userInfo: { hobby }} = { userInfo: { name: 'iyongbao', age: 26, hobby: ['Vue', 'React'] } }; console.log(hobby); // ['Vue', 'React']
这其实就是对象的多次解构
2.2 对象解构过程
我们来聊一聊这个解构赋值的过程是怎么样的。
js
let { username: username } = { username: 'iyongbao', age: 26 };
- 解构: 程序会去
{ username: 'iyongbao', age: 26 }
对象中找属性为username
的值; - 赋值:
找到后
赋值给我们声明
的name
变量,因为ES6
的特性
,如果值一样,我们可以省略
; - 所以说真正
被赋值
的是后者
而不是前者
。
所以总结出为什么报错,age是匹配的模式,aaa才是真正的变量。
2.3 设置默认值
-
和数组一样,解构对象也是可以设置默认值的,大同小异。
jslet { color = 'red' } = {}; let { name, age = 26 } = { name: 'iyongbao' } console.log(color, name, age); // red iyongbao 26
注意 :默认值生效
的条件
是获取的值为undefined
。
js
let { color = 'red' } = { color: undefined };
let { background = 'green' } = { background: null };
console.log(color, background); // red null
三、字符串的解构赋值
3.1 基本用法
-
字符串
也是可以进行解构赋值
的,编辑器会把字符串
转换为一个类似数组
的对象
。jslet [a, b, c, d, e, f, g] = 'iyongbao'; console.log(a, b, c, d, e, f, g); // i y o n g b a
-
我们也可以
解构
出来字符串
的长度
。jslet { length } = 'iyongbao'; console.log(length); // 8
为什么会这样 :首先
程序
会包装
我们的字符串
为一个实例对象
,让这个实例去访问指定的属性或方法,然后获取对象中的length
,最后销毁自己。(其实String在底层字符串是以字符数组的形式保存的。)
四、函数参数的解构赋值
函数
的参数
也是可以进行解构赋值
的
js
function add ([x, y]) {
return x + y;
}
console.log(add([1, 2])); // 3
4.1 参数默认值
-
可以给参数设置默认值(第一种)
jsfunction foo ({ x = 1, y = 2}) { return [x, y]; } foo({ x: 3, y: 4}); // [3, 4] foo({ x: 5 }); // [5, 2] foo({}); // [1, 2]
上面的函数
需要传入
一个对象
,通过解构赋值
得到对应
的值,如果解构失败
则使用默认值
。
-
可以给参数设置默认值(第二种)
jsfunction foo ({ x, y } = { x: 1, y: 2}) { return [x, y]; } foo({ x: 1, y: 2}); // [1, 2] foo({ x: 3 }); // [3, undefined] foo({}); // [undefined, undefined] foo(); // [1, 2]
这种赋值注意
是整体赋值
,只要
我们传入
参数默认值
就不起作用
了。
思考:看一看一下会打印什么值:
js
let newArr = [1, undefined, 2].map((x = 'iyongbao') => x);
console.log(newArr); // ???
五、闲聊
本来想的是码完字去写写代码,维护一下网站,可是写完发现已经快要11点了,今天也是元宵节,就饶过自己,好好睡一觉。真心希望我写的东西能让更多的人看到,也真心希望我写的东西能帮助到一些人,虽然很基础。