发布于 2026-01-06 8 阅读
0

探索 JavaScript 中的解构赋值

探索 JavaScript 中的解构赋值

什么是解构?

解构是 JavaScript 中一个非常酷的特殊语法特性,它允许我们从数组对象或其他可迭代结构中提取值,并将它们赋值给变量。

它是一种无需使用点号或数组索引即可访问数据结构属性或元素的简便方法。

这对我们(用 JavaScript 编写代码的人)有什么好处?

解构有很多好处,可以使我们的代码更简洁、更易读、更易于维护!

  • 提高可读性:解构通过减少对复杂变量赋值和点号表示法的需求来简化代码。
  • 减少样板代码:您可以直接从数据结构中提取值,而无需创建中间变量。
  • 更简洁的代码:解构可以减少实现相同结果所需的代码行数。
  • 灵活性:您可以解构任何类型的数据结构(对象、数组、可迭代对象),使其成为 JavaScript 工具包中用途广泛的工具。

有效的解构🚀使我们能够编写更具表现力、更易于维护更高效的代码,这些代码更容易理解和调试。

基本示例

const person = { name: 'John', age: 30 };
const { name, age } = person;
console.log(name); // "John"
console.log(age); // 30
Enter fullscreen mode Exit fullscreen mode

这里我们解构了一个person具有两个属性的对象:nameage

解构 JavaScript 对象时,提取的值必须与对象中的键完全相同。你不能userNamename`<key>` 行中用 `<key>` 代替
const { name, age } = person;`<key>`。这意味着 `<key>`const { userName, age } = person;行不通。
但是,我们可以在解构对象时使用别名。
例如:

const person = { name: 'John', age: 30 };
const { name:userName, age:userAge } = person;
console.log(userName); // "John"
console.log(userAge); // 30
Enter fullscreen mode Exit fullscreen mode

你很可能第一次接触到对象解构是在导入模块的时候。例如,导入 exec 函数时——

import { exec } from "node:child_process"; // ES Module syntax
Enter fullscreen mode Exit fullscreen mode
const { exec } = require("child_process"); // commonJS syntax
Enter fullscreen mode Exit fullscreen mode

类似地,我们也可以解构数组——

const numbers = [4, 5, 6];
const [x, y, z] = numbers;
console.log(x); // 4
console.log(y); // 5
console.log(z); // 6
Enter fullscreen mode Exit fullscreen mode

在解构数组时,无需使用别名将任何元素分配给自定义变量名。因为数组元素仅仅是值,它们并不绑定任何键。

默认值

解构赋值允许你在对象中不存在该属性时为变量分配默认值。

const person = { name: 'John' };
const { name = 'Anonymous', age } = person; // age will be undefined
console.log(name); // "John"
console.log(age); // undefined
Enter fullscreen mode Exit fullscreen mode

'John'这里并没有用'Anonymous'变量中的值替换字符串值,name因为该值已经存在于对象中。
而——

const person = { name: 'John' };
const { name, age = 30 } = person; // age defaults to 30 if not present
console.log(name); // "John"
console.log(age); // 30
Enter fullscreen mode Exit fullscreen mode

展开语法

展开语法(或称扩展运算符) (...)可以与解构一起使用,将数组的剩余元素或对象的属性捕获到新变量中。

  • 数组的扩展语法 -
const numbers = [1, 2, 3, 4, 5];
const [first, second, ...rest] = numbers;
console.log(first);  // 1
console.log(second); // 2
console.log(rest);    // [3, 4, 5] (remaining elements)
Enter fullscreen mode Exit fullscreen mode
  • 使用对象展开语法 -
const person = { name: 'John', age: 30, city: 'New York' };
const { name, ...info } = person;
console.log(name);  // "John"
console.log(info);   // { age: 30, city: "New York"} (remaining properties)
Enter fullscreen mode Exit fullscreen mode

嵌套解构

解构可以嵌套使用,从深层嵌套的对象或数组中提取值。

const data = {
  user: {
    name: 'Alicia',
    origin: 'Romania',
    eyes: 'blue',
    address: {
      city: 'London',
    }
  }
};

const { user: { name, address: { city } } } = data;
console.log(name);  // "Alicia"
console.log(city);   // "London"
Enter fullscreen mode Exit fullscreen mode

函数参数列表中的解构

假设我们有一个名为credentials- 的JavaScript 对象。

const credentials = {
  name: 'Debajyati',
  age: 20,
  address: {
    city: 'Kolkata',
    state: 'West Bengal',
    country: 'India'
  },
  phone: '',
  email: '',
  hobbies: ['reading', 'listening to music', 'coding', 'watching Anime'],
  skills: {
    programming: true,
    blogging: true,
    singing: false
  }
}
Enter fullscreen mode Exit fullscreen mode

还有一个名为 `is only 1 argument value` 的函数showCredentials,它接受一个对象作为参数,并根据对象的某些属性输出一个字符串。
我们可以这样定义这个函数:

function showCredential(obj) {
  const hasSkill = (skill) => obj.skills[skill];
  console.log(
    `${obj.name} is ${obj.age} years old.\n Lives in ${obj.address.city}, ${obj.address.country}.\n`,
    `He has the following hobbies: ${obj.hobbies.join(", ")}`,
  );
  if (hasSkill("programming")) {
    console.log(`He is a programmer.`);
  }
  if (hasSkill("singing")) {
    console.log(`He is a singer.`);
  }
  if (hasSkill("blogging")) {
    console.log(`He is also a tech blogger.`);
  }
}

Enter fullscreen mode Exit fullscreen mode

用 - 来调用

showCredential(credentials);
Enter fullscreen mode Exit fullscreen mode

得到以下输出 -

Debajyati is 20 years old.
 Lives in Kolkata, India.
 He has the following hobbies: reading, listening to music, coding, watch
ing Anime
He is a programmer.
He is also a tech blogger.
Enter fullscreen mode Exit fullscreen mode

相反,我们可以在定义函数时解构参数列表中的对象参数。像这样——

function showCredential({ name, age, address: { city, country}, hobbies, skills }) {
  const hasSkill = (skill) => skills[skill];
  console.log(
    `${name} is ${age} years old.\n Lives in ${city}, ${country}.\n`,
    `He has the following hobbies: ${hobbies.join(", ")}`,
  );
  if (hasSkill("programming")) {
    console.log(`He is a programmer.`);
  }
  if (hasSkill("singing")) {
    console.log(`He is a singer.`);
  }
  if (hasSkill("blogging")) {
    console.log(`He is also a tech blogger.`);
  }
}
Enter fullscreen mode Exit fullscreen mode

这两种方法都能得出相同的结果。

📝 注意

该函数仍然只接受一个参数。解构并没有增加函数参数列表中的参数数量。

此外,调用该函数的方式也没有改变,仍然是这样——

showCredential(credentials);
Enter fullscreen mode Exit fullscreen mode

那么,为什么要解构函数参数列表中的对象呢?

虽然在函数参数列表中进行解构乍一看可能显得繁琐或乏味,但它有其非常重要的好处。

需要考虑的重要事项

  • 更安全的代码:解构赋值可以通过明确函数需要哪些属性来帮助预防错误。如果传递的对象缺少某个属性,解构赋值会在函数执行期间导致错误,从而有助于及早发现潜在问题。
  • 减少冗余:通过将属性直接提取到参数列表中的变量中,可以避免使用点号表示法重复访问对象属性。这使得函数定义更加简洁清晰。
  • 专注于功能性:通过在参数列表中进行解构,您可以将数据访问逻辑与函数的核心功能分离。这可以改善代码组织,并使函数的用途更加清晰。

字符串解构

就像我们可以解构数组一样,我们也可以将字符串解构为数组元素。这真是巧妙地运用了我们的智能。

const fruit = 'grape';
const [first, second, ...rest] = fruit;
const animal = rest.join('');
console.log(animal); // ape
Enter fullscreen mode Exit fullscreen mode
⚠️ 记住!

当你使用扩展运算符(...)从字符串中提取剩余字符时,你得到的不是一个字符串,而是一个包含这些字符的数组。

解构的一些实用应用示例

  • 无需第三个变量即可进行解构赋值
    传统上,JavaScript 需要使用临时变量来交换两个变量的值。解构赋值提供了一种更简洁、更易读的实现方式。

    • 解构之前:

      let a = 10;
      let b = 20;
      
      let temp = a;
      a = b;
      b = temp;
      console.log(a, b); // Output: 20 10
      
    • 解构之后:

      let a = 10;
      let b = 20;
      
      [a, b] = [b, a];
      
      console.log(a, b); // Output: 20 10
      

    真精致又优雅✨!是不是?

  • 解构函数返回值:函数可以返回多个值,可以是数组或对象。解构可以将这些返回值拆分成单独的变量,从而提高代码的清晰度。
    假设你有一个函数,它从 API 获取数据并返回一个响应对象:

    function getUserUpdates(id) {
      // Simulating some API call with a GET request
      return {
        data: {
          player: response.group.names[id],
          brain: "rotting",
          powerLevel: Number(response.group.power[id]),
          useAsDecoy: true,
        },
        statusCode: Number(response.status),
      };
    }
    

在构建 API 或处理服务器响应时,它具有显著优势,能够提升代码质量和可维护性。
访问各个属性将变得轻而易举,因为您可以在函数调用期间直接将所需的属性从函数返回值中提取到单独的变量中。

const {
  data: {player, useAsDecoy, powerLevel},
  statusCode,
} = getUserUpdates(1);
Enter fullscreen mode Exit fullscreen mode

当函数返回一个对象,而你又需要访问其特定属性值时,务必立即使用解构赋值。
如果你仍然认为在返回值中使用解构赋值并非明智之举,那么以下两个优势或许能让你改变看法——
(A)简化心智模型:解构赋值简化了开发者理解函数数据流所需的思维过程。开发者无需记忆复杂的属性访问链,而是可以专注于解构赋值模式中变量名称所传达的含义。这降低了认知负荷,并有助于更好地理解代码。
(B)减少复杂返回对象的样板代码:
当函数返回具有大量或嵌套属性的对象时,解构赋值可以显著减少访问这些属性所需的样板代码。这使得代码库更加简洁清晰,从而提升整体代码质量。

  • 解构赋值与条件语句结合使用:解构赋值可以与条件语句结合使用,以根据对象的结构处理不同的场景。例如,如果您有一个函数接收一个带有可选属性的对象:

    function greetUser(user) {
      const { name = "Anonymous" } = user || {}; // Destructuring with default value
    
      console.log(`Hello, ${name}!`);
    }
    
    greetUser({ name: "Bob" });       // Output: "Hello, Bob!"
    greetUser({});                    // Output: "Hello, Anonymous!" (no name property)
    greetUser(undefined);           // Output: "Hello, Anonymous!" (function receives no argument)
    
    

结论

在整篇文章中,我们了解到“解构”是 JavaScript 中一项强大而灵活的特性,它可以显著提升代码的可读性、可维护性和效率。通过有效地运用解构技术,你可以编写出更简洁、更清晰、更不易出错的代码。所以,拥抱解构,让你的 JavaScript 技能更上一层楼吧!

如果您觉得这篇文章对您有帮助,如果这篇博客为您的时间和精力增添了价值,请点赞并分享给您的朋友以示支持。

欢迎随时联系我 :)

感谢阅读!🙏🏻
Debajyati Dey倾情撰写💚
我的 GitHub 我的领英 我的每日.dev 我的同伴列表 我的推特

祝您编程愉快!🧑🏽‍💻👩🏽‍​​💻!祝您今天过得愉快!🚀

文章来源:https://dev.to/ddebajyati/exploring-destructuring-in-javascript-5a24