放下解构之锤

2025-06-08

放下解构之锤

解构是 JavaScript 最便捷的功能之一。当我理解了这个看似古怪的语法后,我立刻就被它的强大功能深深吸引。说真的,谁会不喜欢呢?如果我们想解构一个属性,我们完全可以做到。

对象?我们可以解构它。

const { firstName, lastName } = person;
Enter fullscreen mode Exit fullscreen mode

数组?我们可以解构它。

const [person, setPerson] = useState(null);
Enter fullscreen mode Exit fullscreen mode

对象里有对象数组?我们也可以解构它。

const {
  firstName,
  lastName,
  employmentHistory: [
     { company, startDate, endDate, title }
  ]
} = person;
Enter fullscreen mode Exit fullscreen mode

不管你信不信,它甚至对字符串也有效。

const { length } = "hello"; // But don't do this. Just no.
Enter fullscreen mode Exit fullscreen mode

如果没有值,我们想将其设置为默认值,那该怎么办?没问题。

const { firstName = 'Derek', lastName = 'Davis' } = person;
Enter fullscreen mode Exit fullscreen mode

但拥有如此强大的力量,也有可能引发问题。

命名冲突

一旦我们走上解构之路,我们将不可避免地遇到它引起的下一个最常见的问题:变量命名冲突。

const { firstName, lastName } = person1;
// whoops! can't do that.
const { firstName, lastName } = person2;
Enter fullscreen mode Exit fullscreen mode

firstName并且lastName已被占用。那么我们该怎么办呢?解构对此有一个答案。

const {
    firstName: person1FirstName, 
    lastName: person1LastName
} = person1;
const {
    firstName: person2FirstName,
    lastName: person2LastName
} = person2;

// ... later on ...

alert(`
    hello ${person1FirstName} ${person1LastName}
    and ${person2FirstName} ${person2LastName}!
`);
Enter fullscreen mode Exit fullscreen mode

我们重命名了属性来修复错误,但是我们得到了什么?我们得到了几行丑陋的 JavaScript,而且我们person1FirstName不用在里面加点就可以使用。

点符号来救援

看看这个。

// the destructuring lines are gone! 

// ... later on ...

alert(`
    hello ${person1.firstName} ${person1.lastName}
    and ${person2.firstName} ${person2.lastName}!
`);
Enter fullscreen mode Exit fullscreen mode

如果我们使用点符号,我们就不必解构任何东西,我们就没有变量命名冲突,我们的代码更少,而且更具可读性!

我们来看另一个例子。

简写属性名的诱惑

属性名缩写是我最喜欢的 JavaScript 特性之一。我喜欢它的语法简洁明了。

// old school
setPerson({ name: name, city: city });

// shorthand property names. so clean.
setPerson({ name, city });
Enter fullscreen mode Exit fullscreen mode

但有时,当我们尝试使用这个功能时,视野可能会变得狭窄。如果我们需要解构的内容嵌套很深,我们只会制造更多的噪音。

const {
    name,
    demographics: { address: { city } }
} = person; // a game of match the brackets

setPerson({ name, city });
Enter fullscreen mode Exit fullscreen mode

那么答案是什么?

再次使用点符号

我们去掉了解构和所有括号。这样可读性就强多了。

// no destructuring

setPerson({
  name: person.name,
  city: person.demographics.address.city
});
Enter fullscreen mode Exit fullscreen mode

但是,嘿,也许你不想用所有的点。只解构顶层属性可以保持代码的可读性。

// just the right amount of destructuring
const { name, demographics } = person;

setPerson({
  name,
  city: demographics.address.city
});
Enter fullscreen mode Exit fullscreen mode

容易忘记的是,点符号和解构可以结合使用,以提高可读性。例如,如果我们想提取 的属性address,可以这样做:

// not ideal
const {
    demographics: { address: { city, state, zip } }
} = person;

// so much better
const { city, state, zip } = person.demographics.address;
Enter fullscreen mode Exit fullscreen mode

解构是一种在平面形式下非常出色的特性,但当它嵌套时,可读性就会开始迅速下降。

命名歧义

想象一下。你正在尝试理解应用程序中一个你不熟悉的部分。你在一个文件的 200 行代码中,遇到了一个名为 的变量name。它没有局部声明;它只是被用在了某个地方,而你根本不知道它是什么。于是你去查找,发现了这个:

const { name, address, phone } = company;
Enter fullscreen mode Exit fullscreen mode

在这种情况下,使用解构创建了一个过于通用的变量名,因为它移除了变量来源的上下文。如果没有解构,company.name变量名会非常清晰。无需再费力寻找变量。

当我们决定解构某个东西时,尽可能让它靠近使用的地方,特别是当变量名是通用的时候。

概括

  • 当解构导致命名冲突时,这是一种代码异味。它或许没什么问题,但也可能表明你不应该使用解构。
  • 尽量保持解构的简洁,避免括号混乱。结合使用点符号和解构有助于保持简洁。
  • 解构对象应尽可能靠近其实际使用的位置,以提高代码的可读性。过于通用的名称会使代码难以理解。
鏂囩珷鏉ユ簮锛�https://dev.to/derekmt12/put-down-the-destructuring-hammer-3n7d
PREV
使用隐藏的 Google API 从任何域获取图标
NEXT
自动化节点依赖项更新