聊聊 ES6 解构 | 8月更文挑战

469 阅读5分钟

👋大家好,我是Chuck。一个不那么正经但热爱前端的孩儿。

这篇文章经鉴定,初中高级前端甚至包括刚入门的同学都可放心食用🥳。

解构

进入正题,为什么要聊聊解构呢?它作为ES6的一个新特性,虽然出来好久了,但是总会有同学像我一样,提起来新东西都害怕😭(emmm主要是我太菜了,更深层次的不会了)。不过没有关系,这一次不要在害怕了,我在前面扛伤害,你输出,一举拿下它!!!

不善于组织语言,也怕误人子弟,能用代码写出来的我都给大家写出来,方便大家理解!!

思考这样一个问题,此时有一个对象,我们需要把部分属性单独拿出来,在解构出来之前我们会怎么做呢?通常是这样。

let foo = {
  bar: 11,
  baz: 31,
  baq: 42
};

// 此时我们需要单独取出 bar 和 baz 属性
let bar = foo.bar;
let baz = foo.baz;

那有了解构之后我们可以怎么做呢?👇

let foo = {
  bar: 11,
  baz: 31,
  baq: 42
};

// 此时我们需要单独取出 bar 和 baz属性,我们只需要
let { bar, baz } = foo;

(哇哦)有了解构这么轻松的嘛!

敲黑板敲黑板,解构的细节你不知道吧?我来告诉你

作用于谁(或者说对谁用)?

解构的作用对象是 对象数组!!!

解构探秘

在上文中我们有了一个关于对象结构的小demo。那么我们来说说这个demo。

就从 let { bar, baz } = foo; 说起!

实际上这里我是用了一个缩写,完整的写法应该是

let { bar: bar, baz: baz } = foo;

既然是缩写,那么来思考一个问题🤔:到底缩写了哪一部分呢?是缩写了 bar: baz: 部分还是缩写了 : bar: baz 部分呢?

先来抛出答案: 缩写了冒号前面的部分。

这个细节是不能忽视的,很快我们就知道为什么缩写的是前面的部分了。

在此之前我们需要回顾一下之前的知识,在下面这个对象字面量写法中,谁是属性,谁是值呢?

let foo = {
  bar: 42
};

聪明如大家,当然是bar是属性,42是值了呀!!!

对,非常对,这个一点毛病也没有!但是,你知道在解构中谁是属性谁是值吗?😏

嘿嘿嘿,不好意思,在解构中,这个顺序完全相反!这里我画了一个图给大家看一下。

这里这个小细节一定一定要注意哦,顺序是完全相反的。这个很重要!!为什么呢?假如说我们要命名一个和对象里面的属性不一样的名字,如果我们不知道这个细节,那么会出现预料之外的结果!就比如说:

let foo = {
  bar: 11,
  baz: 31
};

// 我们想要将 bar 的值赋值到 a, 将 baz 的值赋值到 b
let { a: bar, b: baz } = foo;
console.log(a); // undefined😖
console.log(b); // undefined😖

// 正确做法!!!
let { bar: a, baz: b } = foo;
console.log(a); // 11 yeah!
console.log(b); // 31 yeah!

假如我们不知道这个细节,出了Bug我们是不是就要怀疑人生了🙈🙈

我知道大家跟我一样更喜欢错误的做法,但是很不幸我们必须得让我们的大脑适应这一变化了!

解构不单单是赋值

思考这样一段代码

let foo = {
  bar: 11,
  baz: 31
};

let { bar: a[0], baz: a[1] } = foo;

运行结果会是怎么样呢?是a[0]等于11,a[1]等于31吗?

很抱歉,这样会出错的,因为在解构的同时,会发生一个声明变量,然后再给变量赋值的过程。既然有声明变量这个过程,那么很容易就可以想到,a[0]不是一个有效的变量名,因此自然而然的就会出错。

对象解构要注意的事情

来看这一段代码

let bar, baz;
let foo = {
  bar: 11,
  baz: 31
};

{ bar, baz } = foo;

console.log(bar); // undefined😨😨😨怎么回事
console.log(baz); // undefined😨😨😨怎么回事

这是因为当对象解构的前面没有 var/let/const 声明的时候,语句左侧的 "{}" 就会被当成一个代码块而不是一个对象。我们只需要用括号把语句括起来就可以得到正确的结果了。

解构中要赋值的不只是变量,任何合法的赋值表达式都可以

这句话要怎么理解呢?我相信看代码你就明白啦。

let foo = {
  bar: 11,
  baz: 31
};

let a = {};
let name = 'bar';

({ bar: a.bar, baz: a.baz } = foo)

({ [name]: a[name] } = foo)

看完这个 demo 我相信你就会明白啦吧~

解构可以重复赋值

对象解构的时候是允许多次列出同一个属性的。比如说:

let foo = {
  bar: 11,
  baz: 31
};

let { bar: X, bar: Y } = foo;
console.log(X); // 11
console.log(Y); // 31

解构表达式的值

解构表达式的值始终是待解构对象。比如说:

let bar, baz, foo1;
let foo = {
  bar: 11,
  baz: 31
};

foo1 = { bar, baz } = foo;
console.log(foo1 === foo); // true

总结

鉴于水平有限,可能文中会有错误,如果各位大佬发现,烦请及时告诉我(下方有微信),我立即更新,以免误人子弟。

解构虽然是不算很大的一个点,但是里面蕴含的细节是需要我们特别注意的,运用好这些细节,我们发挥我们的奇思妙想就有可能发现更好的写法。

我是Chuck,希望本篇文章能够让你有所收获。

赞不赞的无所谓,咱看中的是赞吗?咱看中的是让你明白解构!!!