JavaScript-ES6 神秘的解构赋值

这篇文章之前早已有“提笔画西游”的冲动,苦苦翻阅很多资料终于理解了神秘感十足的解构赋值,可奈何最近忙于工作上的事情挤不出时间更新博客。话不多说、先请JS祖师爷 - Douglas Crockford!

JavaScript-ES6 神秘的解构赋值_第1张图片

 解构赋值:ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。

1、数组解构赋值:

通常定义变量并赋值的时候只能一个一个定义之后再赋值,例如:

let name = 'Destructuring'
let age = 46
let sex = '男'

而ES6允许我们借助数组的解构赋值来这样写:

let [name, age, sex] = ['Destructuring——2', 46, '男']

由上述代码可知,结构赋值本质上是根据左边数组的索引来寻找右边数组对应的索引、之后而赋值。

嵌套数组的解构:

let [name, [hobby], car] = ['马云', ['赚钱'], '奔驰-迈巴赫']
console.log(name, hobby, car) //马云 赚钱 奔驰-迈巴赫

空位数组的解构:如果解构不成功,变量的值就等于undefined

let [, , , age, name, hobby] = [15, 23, 32, 46]
console.log(age, name, hobby) //46 undefined undefined

 剩余参数解构:注意剩余参数的返回值是真数组,arguments是伪数组。

let [name, ...car] = ['马云', '奔驰-迈巴赫', '保时捷-911', '兰博基尼1-大牛']
console.log(name, car) //马云 ["奔驰-迈巴赫", "保时捷-911", "兰博基尼1-大牛"]

 解构失败:若被解构的值不是可遍历的结构,则会解构失败导致报错。

// 报错
let [name] = 1;
let [name] = false;
let [name] = NaN;
let [name] = undefined;
let [name] = null;
let [name] = {};

默认参数:解构赋值时允许像函数传参那样携带默认参数。

let [name = '马云', sex = '女'] = [, '男']
console.log(name, sex) //马云 男

解构顺序是先判断等号右侧数组里面是否可以解析成功,判断解析成功的标准有两个:一是等号右边必须是可遍历的结构、二是判断当前被解构的值是否恒等于undefined,于是就会出现下面有趣的事情:

let [name = '马云'] = [undefined]
name '马云'
let [name = '马云'] = [null]
name null

看到这里,我猜你一定会在控制台去判断undefined == null  结果返回true,既然undefined == null 为什么undefined启用了默认值,而null却没有启用默认值?

原因就是 undefined == null 返回true使用的是 ==(普等) 、undefined === null返回false 而结构赋值时使用的就是 ===(恒等),既然undefined === null 为false ,那么就认为null可以解构成功,所以结果name = null。

默认参数可以是一个函数?这就很有趣了,因为可以通过传递函数得出拥有默认值时 先赋值默认值再去解构?还是先解构如果不成功再去赋值默认值? 或 先解构、如果成功就解构下一个?这是一个值得深思的执行顺序问题,因为我们无法从默认值是其他数据类型时判断这个问题:

function Fn() {
    console.log('函数被调用')
    return '默认值'
}
let [Str = Fn()] = ['解构赋值']

上述代码可以正常解构赋值,运行时 若Fn函数打印了‘函数被调用’,那执行顺序就是先使用默认值、再去解构;

若Fn函数没有打印‘函数被调用’、说明函数未被调用,直接解构成功,执行顺序就是先解构 判断是否成功、若失败再去赋默认值;

JavaScript-ES6 神秘的解构赋值_第2张图片

到现在已经很明确了,解构赋值的执行顺序是 先解构、若成功 则不会再去判断默认值。失败 才会去启用默认值。


2、对象解构赋值:

let { Car, Color , width } = {  Color: 'black', Car: '奔驰'}
console.log(Car,Color, width ) //奔驰 black undefined

对象结构赋值与数组解构赋值的区别在于:数组结构时是按照索引找对应值、而对象则是根据键名寻找对应值,且与次序无关,若键不存在则赋值为undefined。

我们可以借用对象解构赋值很轻松的实现将window对象上的方法赋值到对应的变量上面,例如console.log()

const { log } = console
log('hello word') //hello word

是不是以后开发的时候再也不担心拼错console.log了?仔细想想为什么会这样?

解构赋值时、等号右侧是一个对象、也可以是一个对象的键名。window对象上的console对象里面包含log、error等打印日志的方法,刚好我们需要解构的键名是log,此时就是把console上的log方法单独提列出来赋值给log这个变量,就是这么 so easy!!

对象解构的难点:

引导:很多时候我们会把一个变量 转换为对象的形式,例如:

let lastName = "张三"
let obj = { name : lastName }
console.log(obj) //{name: "张三"}

ES6《属性的简洁表示法》允许在大括号里面,直接写入变量和函数,作为对象的属性和方法,根据ES6这个特效将一个变量转换为对象。

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

let { person : lastName } = { person : '马云' }
console.log(lastName) //马云
console.log(person) //person is not defined

上述代码左边的person找到了右边person的值,但是真正赋值的时候却不是赋值给了自己,而是赋给lastName,也就是说对象的解构赋值机制是先根据等号左侧的属性名、找到右侧的同名属性,之后再赋值给对应的变量,即lastName这个变量。


如果我的博客帮助你解决了开发问题,请不要吝啬你的小红心哦! 


 

你可能感兴趣的:(ES6,JavaScript)