(本文是内森·托马斯(Nathan Thomas)正在进行的一系列技术和软技能系列文章的一部分,内森·托马斯(Nathan Thomas)是在旧金山工作的全栈软件工程师,负责构建非常酷的东西。他之前曾在 Lambda School 工作并就读过 。请单击此处,获得该系列的上一篇文章,一块叫“ 请解释封闭! ”)
介绍
今天,我们将同时变得有点技术和深奥。 ♂️
我们将讨论JavaScript解构背后的概念,如何使用它以及为什么要使用数组或对象变体。
我总是告诉我的读者在开始之前要喝一杯热饮料。 今天,请把您一直拒之门外的零食拿出来,因为它“不健康”。
如果我们要让我们的大脑锻炼一下,那么我们也很值得。
让我们开始吧。 👍
“无论是否信奉一种宗教,以及是否信奉重生,都没有人不欣赏仁慈和同情心。”
- 达赖喇嘛
什么是解构?
从本质上讲,解构的想法是我们从先前创建的对象或数组中单独提取值。
这个想法非常重要。 再读一遍那句话。
Mozilla开发人员网络(MDN)将解构定义为JavaScript中的一项功能,“可以将数组中的值或对象中的属性解压缩为不同的变量。”
这是我们今天要讨论的两种类型的销毁示例:
// Array destructuring
const arrayOfNumbers = [ 1 , 2 , 3 , 4 , 5 ];
const [one, two, three, four, five] = arrayOfNumbers;
// Object destructuring
const objectOfNumbers = { one : 1 , two : 2 , three : 3 , four : 4 , five : 5 };
const { one, two, three, four, five } = objectOfNumbers;
如果您以前从未看过或未使用过销毁功能,那么上面的代码可能看起来有点怪异。 但是不用担心,因为这就是我们在这里的原因! 🙌
第一个示例显示了一个名为arrayOfNumbers
的数组。 在下一行中,发生了一些疯狂的事情。 我们已经切换了arrayOfNumbers
变量名称和[1, 2, 3, 4, 5]
数组分配的位置。 现在,它们已分配给数组中的变量名,看起来像[one, two, three, four, five]
。
这是结构性破坏,我们将在短期内研究其用例和背后的原理。 现在,只需对语法有所了解。
另外,请注意下一个对象分解的示例(下面的代码,因此您不必向上滚动)。 我们从一个名为objectOfNumbers
的变量开始,并为其分配一个具有键-值对的对象:
// Object destructuring
const objectOfNumbers = { one : 1 , two : 2 , three : 3 , four : 4 , five : 5 };
const { one, two, three, four, five } = objectOfNumbers;
就像以前一样,我们为下一行解构切换语法。 但是,这一点有所不同。 我们缺少的键值对的值 one: 1, two: 2
,等等。
我们将在稍后讨论更多。 和以前一样,我希望您习惯语法。
准备学习更多吗?
我们去🔥
“我决定坚持爱。 讨厌的负担实在太大了。”
-小马丁·路德·金博士。
阵列解构:灵活且适应性强
解构的第一种形式是通过使用数组来完成的。 这是我们将要处理的非常简单的代码块:
function outerFunction ( ) {
function firstFunction ( ) {
return 1 ;
}
function secondFunction ( ) {
return 2 ;
}
function thirdFunction ( ) {
return 3 ;
}
return [firstFunction, secondFunction, thirdFunction];
}
const [first, second, third] = outerFunction();
请注意,我们有一个主要函数outerFunction
,其中有三个内部函数; 同样,当我们调用它时, outerFunction
将在数组中返回这三个函数。
这是可能的,因为函数是JavaScript中的“一等公民”,这只是一种过于复杂的说法,即它们可以像其他任何值一样作为值传递或从函数返回!
最后,请注意我们在outerFunction
函数下的代码如下:
const [first, second, third] = outerFunction();
整齐! 现在,关于这一行代码,我想强调一些事情:
- 首先,这就是解构! ✨
- “赋值运算符”(表示“等号”的方法过于复杂)的左侧正在拉出数组中返回的每个函数
- 当我们像这样将它们拉出时,这些函数将由它们的索引引用(这将在一分钟内有意义,因此,如果现在还没有的话,请不要强调)
我们将分别退出这三个功能,因此我们不必像这样引用它们:
const functionsArray = outerFunction();
const first = functionsArray[ 0 ]; // References the first function
const second = functionsArray[ 1 ]; // References the second function
const third = functionsArray[ 2 ]; // References the third function
first(); // Returns 1
second(); // Returns 2
third(); // Returns 3
虽然有效,但很混乱。 在本节的第一个代码块中,我们通过解构抽取了三个函数中的每一个。 之后,我们只能像这样调用函数:
const [first, second, third] = outerFunction();
first(); // Returns 1
数组解构还允许我们操纵要解构的变量名。 我们可以轻松地将函数重命名为完全随机的东西:
const [banana, orange, grapefruit] = outerFunction();
banana(); // Returns 1
orange(); // Returns 2
grapefruit(); // Returns 3
当我们使用数组解构来访问它们时,它们的名称无关紧要的原因是,在数组中,解构基于值的索引而不是名称。
这样做的缺点是,如果我们在分解时只想要第二个数组位置值,则必须编写以下代码:
const [, orange] = outerFunction();
// We have to put the comma in since we need to signify that we're
// choosing "orange" (the second array position)
因为数组解构是基于索引的,所以有时可以通过重命名要解构的内容来利用它,以发挥我们的优势。
例如,这是React中useState
钩子的示例,在其中多次调用它并重命名我们要解构的值:
import React, { useState } from "react" ;
function Button ( props ) {
const [colorState, setColorState] = useState( "red" );
const [textState, setTextState] = useState( "Click me" );
function handleClick ( e ) {
e.preventDefault();
setColorState( "blue" );
setTextState( "Thanks!" );
}
return (
< button style = {{ color: colorState }} onClick = {handleClick} >
{textState}
</ button >
);
}
如果您不了解React或React Hooks,请不要紧张; 从此代码片段中useState
的重要内容是,我们两次使用完全相同的函数( useState
),但对结构化值使用了不同的名称,因此我们不会从具有相同变量的多个变量中得到任何错误名称。 这就是为什么数组分解如此强大的原因!
顺便说一句,让我们看看另一种形式的解构……
对象🔥
对象解构:精确命名
如果阵列是破坏世界的动态橡皮图章,则物体是外科手术且精确的。 ⚕
在数组解构中,因为基于index引用值,所以提取值的顺序很重要。 但是对于对象,您正在基于名称 ( 键值对的键)访问值。 这是一个代码示例:
const exampleObject = {
one : 1 ,
two : 2 ,
three : 3
};
const { one, two, three } = exampleObject;
console .log(one); // Logs 1 to the console
console .log(two); // Logs 2 to the console
console .log(three); // Logs 3 to the console
因为我们基于名称(而不是索引)引用对象内部的键值对,所以可以这样编写代码:
const { three, two, one } = exampleObject;
console .log(three); // Returns 3
console .log(two); // Returns 2
console .log(one); // Returns 1
虽然我们列出项目的顺序是完全不同的,但结果是完全一样的。 这些键名中的每一个仍然在对象内部引用相同的值。
例如,我们可以像这样从对象中拉出two
键值对:
const { two } = exampleObject;
console .log(two); // Logs 2 to the console
这对于完全访问我们希望在对象内部(而不再需要)的内容而言是完美的。 但是,这也意味着我们不能仅仅一次将相同的值解构两次就可以了:
const { two } = exampleObject;
const { two } = exampleObject;
// This throws a SyntaxError since "two" has already been defined
我们将不得不做一些稍微复杂的事情(将two
重命名为newTwoValue
):
const { two } = exampleObject;
const { two : newTwoValue } = exampleObject;
// This is fine since we're renaming "two" to "newTwoValue" in the
// second line
既然我们已经定义了如何使用数组和对象解构,我们可以从理论上进行简要介绍并简要讨论何时使用它们。
“在你所处的地方做点好事; 正是这些点点滴滴使世界不知所措。”
—德斯蒙德·图图(Desmond Tutu)
选择适合工作的工具
最终,将由您决定何时使用对象和数组解构。 作为工程师,您将获得知道何时以及如何使用某些工具的能力。
这是我尝试遵循何时使用对象或数组解构的准则的列表:
- 您是否需要在同一作用域/文件中多次从函数中提取值? 如果是这样,请使用数组解构,因为您可以根据需要重命名它们。
- 您是否希望能够在对值进行解构时重命名它们? 尽管对象是可能的,但使用数组要干净得多。
- 您是否需要访问从前端框架中的父组件传递来的值? 如果是这样,请使用对象分解。
- 您是否只想在进行销毁时提取所需的值(而没有其他值)? 如果是这样,请使用对象分解。
结论
希望您喜欢这篇关于销毁的文章。 它是JavaScript中如此强大的工具,因为它可以快速清理代码并允许您执行各种有趣的事情。
您现在应该可以放心地进行任何采访,并使用此语法来发挥自己的优势。
谢谢阅读。 🔥
内森
( Twitter , GitHub , LinkedIn和Portfolio网站 )
From: https://hackernoon.com/wtf-is-destructuring-in-javascript-6t5g32wu