现代 JavaScript 的最佳实践 - 第 2 部分

在这篇文章的入门部分中,探索了现代 JavaScript 的基础和最佳实践,以编写更多的代码和效率。但对于这些人来说,请注意,最好的方式是了解和了解。

8. Encadenamiento 可选 (?.)

与对象或结构一起工作时,必须验证是否存在预先存在的属性。 El **operador de encadenamiento opcional** (`?.`) es una herramienta poderosa que simplifica esta tarea, evitando errores de acceso a propiedades de valores de valores 'null' or 'undefined'.

为什么有用?

想象一下,如果有一个完整的对象结构,并且没有任何安全性,那么所有的属性都存在。如果是可选的,请在最后一步验证手册,然后将其放入大海中,并使其清晰易读。对于操作符“?.”,如果中间属性不存在,则可以获取“未定义”属性。

基本示例

const producto = {};
const impuesto = producto?.precio?.impuesto;
console.log(impuesto); // undefined

在这种情况下,“producto”不包含“precio”属性,并且在一般错误中可能会出现“未定义”选项。

Ejemplo con un objeto más complejo

想象一下不同属性的产品列表,以及没有明确定义的产品:

const productos = [
  { nombre: 'Laptop', detalles: { precio: 1000 } },
  { nombre: 'Teléfono', detalles: null },
  { nombre: 'Tablet', detalles: { precio: 500, impuesto: 50 } }
];

// Acceso seguro a la propiedad 'impuesto' de cada producto
productos.forEach(producto => {
  const impuesto = producto?.detalles?.impuesto;
  console.log(impuesto); // undefined, null o el valor real
});

因此,在选择“产品详细信息”时,不允许出现任何错误,包括“详细信息”和“空”或其他内容。

如何改善您的代码?

  • Evita errores de acceso a propiedades nulas o indefinidas。
  • 简化代码,验证肖恩的安全性并清晰易读。
  • 允许对未完成或不完整的数据进行操作,但您可以对 API 响应或数据基础进行操作。
  • 奖励:Encadenamiento 可选功能

    El encadenamiento optioncional también se puede usar con funciones, lo cual es muy util til cuando tienes funciones que pueden no estar definidas en un object:

    const usuario = { nombre: 'Juan', obtenerEdad: null };
    const edad = usuario.obtenerEdad?.();
    console.log(edad); // undefined

    但是,函数“obtenerEdad”没有定义(即“null”),但如果不会产生错误,则简单地返回“undefined”。

    9. Usa async/await para manejo de asincronía

    在 JavaScript 中执行与操作相关的操作,可以获取 API 或阅读档案的数据,并获得“async/await”的sintaxis,这是您最好的朋友。在使用 `.then()` 和 `.catch()`、`async/await` 的过程中,可以将脚本编写为清晰易读的脚本,类似于编写 sincrónico 脚本。

    为什么使用 async/await?

  • 简单易读:Evitas las “cadenas de promesas” que pueden volverse complicadas de leer y mantener。
  • 直观上的错误提示:使用 try/catch 可以发现错误很多,例如 claro que usar .catch()。
  • 更精确的控制:允许用户等待功能部分,以方便地控制流体并完成所有任务。
  • 基本使用示例:

    Supongamos que estamos trabajando con una API que devuelve datos.使用 `async/await` 和 `.then()` 可以很方便地进行后续操作:

    async function obtenerDatos() {
      try {
        const respuesta = await fetch('https://api.ejemplo.com/datos');
        if (!respuesta.ok) {
          throw new Error('Error al obtener los datos');
        }
        const datos = await respuesta.json();
        console.log(datos);
      } catch (error) {
        console.error('Error:', error.message);
      }
    }

    Ejemplo práctico: 获得 API 数据和 UI 的大部分数据

    想象一下网络页面需要使用 API 的大部分信息。使用“async/await”来获取数据和渲染:

    // Función para obtener y mostrar los datos de usuarios
    async function obtenerUsuarios() {
      try {
        const respuesta = await fetch('https://api.ejemplo.com/usuarios');
        if (!respuesta.ok) {
          throw new Error('No se pudieron cargar los usuarios');
        }
        const usuarios = await respuesta.json();
        mostrarUsuariosEnUI(usuarios);
      } catch (error) {
        console.error('Hubo un problema con la carga de los usuarios:', error);
        alert('Error al cargar los usuarios. Intenta más tarde.');
      }
    }
    
    // Función para renderizar usuarios en el HTML
    function mostrarUsuariosEnUI(usuarios) {
      const contenedor = document.getElementById('contenedor-usuarios');
      contenedor.innerHTML = usuarios.map(usuario => `
        

    ${usuario.nombre}

    Email: ${usuario.email}

    `).join(''); } // Llamada a la función para obtener y mostrar los usuarios obtenerUsuarios();

    ¿Qué mejoramos con async/await?

  • 错误说明:Usamos 尝试/捕获在获取数据期间发生的错误,这是一个红色或 API 问题。
  • 代码更清晰:La estructura de waiting hace que el Flujo del código se lea de manera secuencial, como si fuera código sincrónico。
  • Evita el anidamiento:Con async/await puedes evitar los callbacks anidados (el famoso "callback hell") y las promesas encadenadas。
  • 使用“async/await”不可以单独处理这些问题,因为它可以帮助您轻松地清理和维护大型广场的项目。 ¡Es una herramienta poderosa que deberías incorporar siempre que trabajes con asincronía en JavaScript!

    10. 对象的现代方法

    在 JavaScript 中使用对象进行工作,是与 claves 和 los valores 相关的必要条件,或者包括额外的 claves 和 valores。现代方法包括“Object.entries()”、“Object.values()”和“Object.keys()”,这些方法非常简单易读。

    对象.keys()

    这是开发对象的所有方法的方法。这是唯一需要加入的 las claves y no a los valores。

    **示例:**

    const obj = { a: 1, b: 2, c: 3 };
    const claves = Object.keys(obj);
    console.log(claves); // ["a", "b", "c"]

    对象.值()

    开发对象属性的所有价值。 Perfecto cuando alone necesitas los valores sin las claves.

    **示例:**

    const obj = { a: 1, b: 2, c: 3 };
    const valores = Object.values(obj);
    console.log(valores); // [1, 2, 3]

    对象.entries()

    这是一种通用的方法。开发数组中的数组,并在子数组中使用 clave 和 su valor 对应项。这就是我们在单独操作中使用的所有方法。

    **示例:**

    const obj = { a: 1, b: 2, c: 3 };
    Object.entries(obj).forEach(([clave, valor]) => {
      console.log(`La clave ${clave} tiene el valor ${valor}`);
    });

    奖励:Iteración con for...of

    ¿Sabías que puedes comminar estos métodos con `for...of' para hacer tu código aún más limpio?使用 `Object.entries()` 时可以使用:

    **示例:**

    const obj = { a: 1, b: 2, c: 3 };
    for (const [clave, valor] of Object.entries(obj)) {
      console.log(`La clave ${clave} tiene el valor ${valor}`);
    }

    这是一种非常灵活且易于阅读的方式,特别是对大型或复杂的物体进行的加工。

    11. 美国地图没有原始内容

    需要使用“Map”来使用 Sean cadenas 或 símbolos 的相关价值。 Es más 鲁棒 y mantiene el Tipo el orden de las claves。

    **示例:**

    const mapa = new Map();
    const clave = { id: 1 };
    mapa.set(clave, 'valor');
    console.log(mapa.get(clave)); // 'valor'

    12. 使用 claves únicas 符号

    JavaScript 中的“Symbol”特性允许创建不可变的类,并且需要保证其勇气和可访问的意外情况。这些符号没有任何中间方法,比如`Object.keys()`、`for...in`、`JSON.stringify()`,这就是“神秘”的私有价值的完美实现。

    为什么使用 Symbol?

    使用文本工具栏上的对象属性,可以轻松操作或理解。禁止通行,这些符号可以保护海洋,包括奶油符号和错误名称。但是,在对象属性枚举中没有任何符号。

    基本示例:

    const obj = {};
    const claveOculta = Symbol('oculta');
    obj[claveOculta] = 'valor secreto';
    console.log(obj[claveOculta]); // 'valor secreto'

    例如,“claveOculta” es única,您可以创建其他“Symbol('oculta')”,完全区别于“obj”的勇气。

    例如:将 Symbol 与 Object.defineProperty 组合

    包括将“Symbol”与“Object.defineProperty”结合使用来提供控制对象的属性,但属性不可以枚举。

    const claveSecreta = Symbol('secreta');
    const obj = {};
    
    Object.defineProperty(obj, claveSecreta, {
      value: 'información confidencial',
      enumerable: false,  // La propiedad no será enumerable
      writable: false,    // La propiedad no será modificable
    });
    
    console.log(obj[claveSecreta]);  // 'información confidencial'
    console.log(Object.keys(obj));   // []

    例如,“claveSecreta”没有对对象的枚举进行说明,但理想的“私人”价值是不可访问或因意外而修改的。

    注意事项:

  • 符号与属性名称冲突,特别是与 API 的图书馆相关的符号。
  • 如果没有任何“私人”限制,则肖恩无法以传统方式访问,成为数据完整性的保护者。
  • 有十个符号序列化为 JSON,因为需要传输数据,因此需要使用 Manera adecuada 的属性符号。
  • 13. JSON 的十个 cuidado 和 números grandes

    在 JavaScript 中,manejar números grandes puede ser un verdadero reto。该“Number”类型是代表输入值的限制:输入密码为“9007199254740991”(与“Number.MAX_SAFE_INTEGER”一致)。如果您打算对这些重要的数字进行操作,请务必做到精确,以消除应用中的一般错误。

    例如,想象一下外部 API 的编号:

    console.log(
      JSON.parse('{"id": 9007199254740999}')
    ); 
    // Salida: { id: 9007199254741000 } (precisión perdida)

    例如,数字“9007199254740999”会被错误地编码为“9007199254741000”。这就是应用程序中出现的问题,如无法识别或金融问题。

    **¿Cómo evitar este Problema?**

    这是一个关于“BigInt”的解决方案,它是 ECMAScript 2020 的介绍。“BigInt”在精确度方面具有很大的优势。但是,JSON 不支持“BigInt”格式,因此需要转换序列号和序列号,并且需要转换序列号。

    Aquí te dejo un ejemplo de cómo podrías hacerlo:

    BigInt 和 JSON.stringify 的解决方案

    const data = { id: 9007199254740999n }; // Usa BigInt para manejar el número grande
    console.log(
      JSON.stringify(data, (key, value) => {
        if (typeof value === 'bigint') {
          return value.toString(); // Convierte BigInt a cadena
        }
        return value;
      })
    );
    // Salida: {"id":"9007199254740999"}

    当您使用时,请确保重要数据的精确度。需要新的数字,单独连接新的“BigInt”:

    const parsedData = JSON.parse('{"id":"9007199254740999"}', (key, value) => {
      if (key === 'id') {
        return BigInt(value); // Convierte la cadena a BigInt
      }
      return value;
    });
    console.log(parsedData.id); // Salida: 9007199254740999n

    其他策略

    如果您不希望使用“BigInt”或其他方式进行操作,则可以使用 JSON 来简单地计算出一些重要的数据。这就是转换过程中的精确度问题。

    **示例:**

    const data = { id: '9007199254740999' }; // Almacena el número como cadena
    console.log(data.id); // Usa la cadena directamente cuando sea necesario

    为什么重要?

    重要的数字并不是单独的,而是计算精度的关键,它是数据的**整体**。这是特别重要的,它与三项 API 或系统的 API 相关,但没有完整的控制。一些错误的解释是您的应用程序中出现的错误,以及评论家中的数据错误,例如金融交易或数据基础上的身份识别。

    Recuerda:**不忽略精度限制**。 Aunque puede parecer un detalle pequeño, es un are donde las aplicaciones pueden Fallar de manera inesperada y costosa.

    14. Maneja expresiones en Sentencias if de forma explícita

    在 JavaScript 中,“if”语句隐含地表达了“真”或“假”的值,因此可以得出一般结果,因为它们之间没有任何关联。在某些情况下,我们建议您对避免错误的情况进行明确的比较,并在代码的合法性方面取得显着的效果。

    “真”或“假”的含义是什么?

  • “Falsy” se refiere a valores que se recognizes equales a false cuando se evalúan en una expresión condicional。例如:0、“”(cadena vacía)、null、未定义、NaN。
  • “真实”儿子todos los valores que no son falsy,es decir,cualquier valor que no sea uno de los anteriores。例如:cualquier número différente de 0、cualquier cadena no vacía、los objetos 等。
  • Ejemplo implícito (puede dar resultados inesperados)

    const value = 0; // Aquí el valor es 0, que es "falsy"
    if (value) {
      console.log('Esto no se ejecutará porque 0 es "falsy".');
    }

    在前面的例子中,如果没有执行条件,则将“0”视为“虚假”。由于禁运,侦查人员可能会遇到更大的困难。

    Ejemplo explícito(最重要的合法性)

    const value = 0;
    // Comprobación explícita para asegurarse de que value no sea 0
    if (value !== 0) {
      console.log('Esto se ejecutará solo si value no es 0.');
    } else {
      console.log('Esto se ejecutará porque value es 0.');
    }

    **Consejo:** Siempre que estés tratando con valores que puedan ser falsy, como `0`, `null`, `false` or `""`, es mejor ser explícito en tu compación.我们保证逻辑上的执行符合预期,并且不存在隐含的强制行为。

    其他含糊不清的意思

    请考虑与“null”、“[]”或“{}”相关的对象。 Si haces algo como esto:

    const obj = [];
    if (obj) {
      console.log('El objeto es truthy');
    } else {
      console.log('El objeto es falsy');
    }

    Aunque `[]` (un arreglo vacío) es un object válido y "truthy", puede llevar a confusion en el futuro si no entiendes bien el comportamiento. Envez de la coerción implícita, lo mejor es hacer comparaciones más explícitas, como:

    const obj = [];
    if (obj !== null && obj.length > 0) {
      console.log('El objeto no está vacío');
    } else {
      console.log('El objeto está vacío o es nulo');
    }

    为什么重要?

    通过明确的形式定义条件,可以减少由 JavaScript 自动强制转换引起的错误。 Este enfoque hace que tu código sea más claro, 清晰易读且可预测。但是,我认为,其他角色(o túmismo en el futuro)将在 JavaScript 中快速记录逻辑。

    15. Usa igualdad estricta (===) siempre que sea posible

    **JavaScript** 提供的操作符与不受限制的操作符(`==`)有关。这意味着我们可以**强制**,这意味着将价值转换为比较之前的价值。这可能会产生一些结果**sorprendentemente inesperados** y muy difíciles depurar。

    举例来说:

    console.log([] == ![]); // true (sorprendente y poco intuitivo)

    这就是我们的目标。 El 操作符 `==` 比较 `[]` (un arreglo vacío) con `![]` (que resulta ser `false`, ya que `[]` se thinka un valor verdadero y `![]` lo conviete a `false`)。由于 JavaScript 的内部强制执行限制,它的结果是无效的,没有任何感觉。

    为什么会发生这种情况?

    JavaScript 可以帮助您进行比较和比较。在这种情况下,在“[]”空位中,将“错误”与“![]”的布尔值进行比较。强制措施可能会导致出现一些错误和识别困难。

    Consejo: 美国 siempre la igualdad estricta

    Para evitar estos Problemas, siempre que sea posible, debes usar **igualdad estricta** (`===`)。两者之间存在差异**没有实现强制**。这意味着比较限制力量的变量的勇气。

    console.log([] === ![]); // false (como se espera)

    更多示例

    解决以下问题:

    console.log(0 == '');  // true (porque 0 se convierte a '' antes de la comparación)
    console.log(0 === ''); // false (porque 0 y '' son de tipos diferentes)
    
    console.log(false == 'false'); // false (comparación de tipo booleano con cadena)
    console.log(false === 'false'); // false (diferente tipo y valor)
    
    console.log(null == undefined); // true (pero no son lo mismo, aunque lo pasen con `==`)
    console.log(null === undefined); // false (compara tipo y valor, y son distintos)

    ¿Por qué es importante usar ===?

  • 预测和配置:Usar === 与预测进行比较,但不能转换为类型。
  • 检测器遇到的困难:您可能会遇到一系列重大而复杂的错误,但与强制提示相关的错误却非常困难。
  • 代码的主要优点:可以帮助其他开发者(o para ti missmo en el futuro)将代码与显式比较进行比较,避免隐式转换的混乱。