Heim >Web-Frontend >js-Tutorial >Best Practices in modernem JavaScript – Teil 2

Best Practices in modernem JavaScript – Teil 2

Patricia Arquette
Patricia ArquetteOriginal
2024-12-08 16:09:12680Durchsuche

Mejores Prácticas en JavaScript Moderno - Parte 2

Im ersten Teil dieses Artikels haben wir die Grundlagen des modernen JavaScript und einige wesentliche Best Practices untersucht, um saubereren und effizienteren Code zu schreiben. Aber als Entwickler wissen wir, dass es immer mehr zu lernen und zu verbessern gibt.

8. Optionale Verkettung (?.)

Bei der Arbeit mit Objekten oder verschachtelten Strukturen müssen wir manchmal prüfen, ob eine Eigenschaft vorhanden ist, bevor wir versuchen, darauf zuzugreifen. Der optionale Verkettungsoperator (?.) ist ein leistungsstarkes Tool, das diese Aufgabe vereinfacht und Fehler beim Zugriff auf Eigenschaften von Null- oder undefinierten Werten vermeidet.

Warum ist es nützlich?

Stellen Sie sich vor, Sie haben eine komplexe Objektstruktur und sind sich nicht sicher, ob bestimmte Eigenschaften darin vorhanden sind. Ohne optionale Verkettung müssten Sie bei jedem Schritt manuelle Überprüfungen durchführen, was Ihren Code länger und weniger lesbar machen kann. Mit dem ?-Operator können Sie sicher auf Eigenschaften zugreifen und undefiniert werden, wenn eine der Zwischeneigenschaften nicht vorhanden ist.

Einfaches Beispiel

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

Da das Produkt in diesem Fall nicht über die Preiseigenschaft verfügt, gibt die optionale Verkettung undefiniert zurück, anstatt einen Fehler zu generieren.

Beispiel mit einem komplexeren Objekt

Stellen Sie sich vor, Sie haben eine Liste von Produkten mit unterschiedlichen Eigenschaften, von denen einige möglicherweise leer oder undefiniert sind:

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
});

In diesem Beispiel können wir durch die optionale Verkettung Fehler beim Zugriff auf „product.details.tax“ vermeiden, selbst wenn „details“ null ist oder nicht vorhanden ist.

Wie verbessert es Ihren Code?

  • Vermeiden Sie Zugriffsfehler auf Null- oder undefinierte Eigenschaften.
  • Vereinfacht den Code und macht Sicherheitsüberprüfungen sauberer und lesbarer.
  • Ermöglicht Ihnen die Arbeit mit unsicheren oder unvollständigen Daten, was sehr häufig vorkommt, wenn Sie mit Antworten von APIs oder Datenbanken arbeiten.

Bonus: Optionale Verkettung mit Funktionen

Optionale Verkettung kann auch mit Funktionen verwendet werden, was sehr nützlich ist, wenn Sie Funktionen haben, die möglicherweise nicht für ein Objekt definiert sind:

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

Hier ist die getAge-Funktion undefiniert (sie ist null), aber sie gibt keinen Fehler aus, sondern gibt nur undefiniert zurück.

9. Verwenden Sie async/await für die asynchrone Verarbeitung

Wenn Sie mit asynchronen Vorgängen in JavaScript arbeiten, wie z. B. dem Abrufen von Daten von einer API oder dem Lesen von Dateien, kann die async/await-Syntax Ihr bester Freund sein. Anstatt Versprechen mit .then() und .catch() zu verwenden, können Sie mit async/await asynchronen Code auf sauberere und besser lesbare Weise schreiben, ähnlich wie wir synchronen Code schreiben würden.

Warum async/await verwenden?

  • Einfachheit und Lesbarkeit:Sie vermeiden „Versprechensketten“, deren Lesung und Pflege kompliziert werden kann.
  • Intuitivere Fehlerbehandlung:Die Verwendung von try/catch zur Fehlerbehandlung ist viel klarer als die Verwendung von .catch().
  • Präzisere Steuerung:Ermöglicht die Verwendung von „await“ an einer beliebigen Stelle in der Funktion, was die Steuerung komplexerer asynchroner Abläufe erleichtert.

Grundlegendes Anwendungsbeispiel:

Angenommen, wir arbeiten mit einer API, die Daten zurückgibt. Durch die Verwendung von async/await anstelle von .then() ist der Ablauf viel einfacher zu verfolgen:

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

Praxisbeispiel: Daten von einer API abrufen und in der Benutzeroberfläche anzeigen

Stellen Sie sich vor, Sie haben eine Webseite, auf der Sie Benutzerinformationen von einer API anzeigen müssen. Hier ist ein Beispiel dafür, wie Sie mit async/await die Daten abrufen und an die Schnittstelle rendern können:

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
});

Object.values()

Gibt ein Array mit allen Werten der Eigenschaften eines Objekts zurück. Perfekt, wenn Sie nur die Werte ohne Schlüssel benötigen.

Beispiel:

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

Object.entries()

Dies ist die vielseitigste Methode. Gibt ein Array von Arrays zurück, wobei jedes Unterarray einen Schlüssel und den entsprechenden Wert enthält. Dies ist nützlich, wenn Sie in einem einzigen Vorgang sowohl mit Schlüsseln als auch mit Werten arbeiten möchten.

Beispiel:

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);
  }
}

Bonus: Iteration mit for...of

Wussten Sie, dass Sie diese Methoden mit for...of kombinieren können, um Ihren Code noch sauberer zu machen? Hier ist ein Beispiel mit Object.entries():

Beispiel:

// 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 => `
    <div>



<h3>
  
  
  ¿Qué mejoramos con async/await?
</h3>

<ol>
<li>
<strong>Manejo claro de errores:</strong> Usamos try/catch para capturar cualquier error que pueda ocurrir durante la obtención de datos, ya sea un problema con la red o con la API.</li>
<li>
<strong>Código más legible:</strong> La estructura de await hace que el flujo del código se lea de manera secuencial, como si fuera código sincrónico.</li>
<li>
<strong>Evita el anidamiento:</strong> Con async/await puedes evitar los callbacks anidados (el famoso "callback hell") y las promesas encadenadas.</li>
</ol>

<p>Usar async/await no solo mejora la calidad de tu código, sino que también hace que sea mucho más fácil depurar y mantener proyectos a largo plazo. ¡Es una herramienta poderosa que deberías incorporar siempre que trabajes con asincronía en JavaScript!</p>

<h2>
  
  
  10. Métodos modernos para objetos
</h2>

<p>Cuando trabajamos con objetos en JavaScript, es común que necesitemos iterar sobre las claves y los valores, o incluso extraer solo las claves o valores. Los métodos modernos como Object.entries(), Object.values() y Object.keys() hacen que estas tareas sean mucho más fáciles y legibles.</p>

<h3>
  
  
  Object.keys()
</h3>

<p>Este método devuelve un array con todas las claves de un objeto. Es útil cuando solo necesitas acceder a las claves y no a los valores.</p>

<p><strong>Ejemplo:</strong><br>
</p>

<pre class="brush:php;toolbar:false">const obj = { a: 1, b: 2, c: 3 };
const claves = Object.keys(obj);
console.log(claves); // ["a", "b", "c"]

Dieser Ansatz ist sauberer und einfacher zu lesen, insbesondere wenn Sie mit großen oder komplexen Objekten arbeiten.

11. Verwenden Sie Map für nicht-primitive Schlüssel

Wenn Sie Werte mit Schlüsseln verknüpfen müssen, die keine Zeichenfolgen oder Symbole sind, verwenden Sie Map. Es ist robuster und behält die Art und Reihenfolge der Schlüssel bei.

Beispiel:

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

12. Verwenden Sie Symbol für eindeutige Schlüssel

Symbole sind eine JavaScript-Funktion, mit der Sie eindeutige und unveränderliche Schlüssel erstellen können. Dies macht sie zu einem leistungsstarken Werkzeug, wenn wir sicherstellen müssen, dass ein Wert nicht versehentlich überschrieben oder darauf zugegriffen wird. Auf Symbole kann nicht mit Methoden wie Object.keys(), for...in oder JSON.stringify() zugegriffen werden, was sie perfekt für private oder „versteckte“ Werte macht.

Warum Symbol verwenden?

Wenn wir Eigenschaften eines Objekts mithilfe von Schlüsseln wie Textzeichenfolgen erstellen, können diese leicht manipuliert oder überschrieben werden. Allerdings stellen Symbole sicher, dass jeder Schlüssel einzigartig ist, auch wenn wir Symbole mit demselben Namen erstellen. Darüber hinaus werden Symbole nicht in Objekteigenschaftenaufzählungen angezeigt.

Einfaches Beispiel:

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
});

In diesem Beispiel ist der Schlüssel „hiddenKey“ eindeutig, und obwohl ein anderer Teil unseres Codes ein anderes Symbol („versteckt“) hätte erstellen können, wäre es völlig anders und hätte keinen Einfluss auf den in obj gespeicherten Wert.

Erweitertes Beispiel: Symbol mit Object.defineProperty kombinieren

Sie können Symbol sogar zusammen mit Object.defineProperty verwenden, um Objekten Eigenschaften auf kontrolliertere Weise hinzuzufügen und sicherzustellen, dass die Eigenschaften nicht aufzählbar sind.

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

In diesem Beispiel wird SecretKey nicht in der Schlüsselaufzählung des Objekts angezeigt, was es ideal für „private“ Werte macht, auf die nicht versehentlich zugegriffen oder die geändert werden sollten.

Überlegungen:

  • Symbole sind nützlich, um Konflikte bei Eigenschaftsnamen zu vermeiden, insbesondere bei der Arbeit mit Bibliotheken oder APIs von Drittanbietern.
  • Obwohl Symbole nicht streng „privat“ sind, trägt die Tatsache, dass sie auf herkömmliche Weise nicht zugänglich sind, dazu bei, die Integrität der Daten zu schützen.
  • Bitte beachten Sie, dass Symbole nicht in JSON serialisiert werden können. Wenn Sie also Daten übertragen müssen, achten Sie darauf, die Symboleigenschaften entsprechend zu behandeln.

13. Seien Sie vorsichtig mit JSON und großen Zahlen

In JavaScript kann der Umgang mit großen Zahlen eine echte Herausforderung sein. Der Datentyp „Zahl“ hat eine Grenze für die genaue Darstellung von Ganzzahlen: Der größte sichere Ganzzahlwert ist 9007199254740991 (auch bekannt als Number.MAX_SAFE_INTEGER). Wenn Sie versuchen, mit größeren Zahlen zu arbeiten, kann es zu Präzisionsverlusten kommen, was zu Fehlern in Ihrer Anwendung führen kann.

Stellen Sie sich zum Beispiel vor, Sie erhalten eine große Zahl von einer externen API:

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);
  }
}

Wie Sie sehen, wird die Nummer 9007199254740999 fälschlicherweise in 9007199254741000 umgewandelt. Dies kann problematisch sein, wenn die Nummer für Ihre Anwendung von entscheidender Bedeutung ist, beispielsweise eine eindeutige Kennung oder ein finanzieller Betrag.

Wie vermeide ich dieses Problem?

Eine einfache und elegante Lösung ist die Verwendung des Datentyps BigInt, der in ECMAScript 2020 eingeführt wurde. BigInt kann viel größere Zahlen verarbeiten, ohne an Präzision zu verlieren. JSON verarbeitet BigInt jedoch nicht nativ, daher müssen Sie Zahlen beim Serialisieren in Zeichenfolgen konvertieren und sie dann beim Deserialisieren wieder zurückkonvertieren.

Hier ist ein Beispiel, wie Sie es tun könnten:

Lösung mit BigInt und JSON.stringify

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

Mit diesem Ansatz können Sie die Genauigkeit großer Zahlen aufrechterhalten, ohne wichtige Daten zu verlieren. Wenn Sie die Nummer erneut benötigen, konvertieren Sie sie einfach wieder in BigInt:

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
});

Andere Strategien

Wenn Sie nicht mit BigInt arbeiten möchten oder die Leistung ein Problem darstellt, besteht eine andere Strategie darin, große Zahlen einfach als Zeichenfolgen in JSON zu behandeln. Dies vermeidet das Präzisionsproblem auf Kosten der Konvertierungen in Ihrem Code.

Beispiel:

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

Warum ist es wichtig?

Der richtige Umgang mit großen Zahlen ist nicht nur entscheidend für die Genauigkeit der Berechnungen, sondern auch für die Wahrung der Datenintegrität. Dies ist besonders wichtig, wenn Sie mit APIs oder Systemen von Drittanbietern arbeiten, die Sie nicht vollständig kontrollieren können. Eine falsch interpretierte Zahl könnte zu Fehlern in Ihrer Anwendung oder, schlimmer noch, zu Fehlern in Daten führen, die kritisch sein könnten, wie z. B. bei der Verarbeitung von Finanztransaktionen oder eindeutigen Identifikatoren in Datenbanken.

Denken Sie daran: Präzisionsgrenzen nicht ignorieren. Obwohl es wie ein kleines Detail erscheinen mag, ist es ein Bereich, in dem Anwendungen auf unerwartete und kostspielige Weise ausfallen können.

14. Behandeln Sie Ausdrücke in if-Anweisungen explizit

In JavaScript konvertieren if-Anweisungen Ausdrücke implizit in „wahre“ oder „falsche“ Werte, was zu unerwarteten Ergebnissen führen kann, wenn dieses Verhalten nicht berücksichtigt wird. Obwohl dieses Verhalten manchmal nützlich sein kann, wird empfohlen, es im Vergleich explizit anzugeben, um subtile Fehler zu vermeiden und die Lesbarkeit des Codes zu verbessern.

Was bedeutet „wahr“ oder „falsch“?

  • „Falsch“ bezieht sich auf Werte, die bei der Auswertung in einem bedingten Ausdruck als gleichwertig mit „falsch“ betrachtet werden. Beispiele: 0, „“ (leerer String), null, undefiniert, NaN.
  • „Wahrhaft“ sind alle Werte, die nicht falsch sind, also jeder Wert, der nicht einer der oben genannten ist. Beispiel: jede Zahl außer 0, jede nicht leere Zeichenfolge, Objekte usw.

Implizites Beispiel (kann zu unerwarteten Ergebnissen führen)

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

Im obigen Beispiel wird die Bedingung nicht ausgeführt, da 0 als „falsch“ gilt. Dieses Verhalten kann jedoch bei der Arbeit mit komplexeren Werten schwer zu erkennen sein.

Explizites Beispiel (besser für die Lesbarkeit)

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
});

Tipp: Wann immer Sie es mit Werten zu tun haben, die falsch sein können, wie z. B. 0, null, falsch oder „“, ist es am besten, in Ihrem Vergleich explizit zu sein. Auf diese Weise stellen Sie sicher, dass die Logik gemäß Ihren Erwartungen ausgeführt wird und nicht aufgrund impliziten Typzwangsverhaltens.

Ein weiteres Beispiel mit mehrdeutigen Werten

Angenommen, Sie haben ein Objekt, das null sein kann, ein leeres Array [] oder ein leeres Objekt {}. Wenn Sie so etwas tun:

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

Obwohl [] (ein leeres Array) ein gültiges und wahrheitsgemäßes Objekt ist, kann es in Zukunft zu Verwirrung führen, wenn Sie das Verhalten nicht vollständig verstehen. Anstatt sich auf impliziten Zwang zu verlassen, ist es am besten, explizitere Vergleiche anzustellen, wie zum Beispiel:

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);
  }
}

Warum ist es wichtig?

Durch die explizite Definition von Bedingungen verringern Sie das Risiko von Fehlern, die durch den automatischen Zwang von JavaScript verursacht werden. Dieser Ansatz macht Ihren Code klarer, lesbarer und vorhersehbarer. Darüber hinaus verbessert es die Wartbarkeit, da andere Personen (oder Sie selbst in Zukunft) die Logik schnell verstehen können, ohne sich an das implizite Verhalten falscher Werte in JavaScript erinnern zu müssen.

15. Verwenden Sie nach Möglichkeit strikte Gleichheit (===).

Eines der verwirrendsten Verhaltensweisen von JavaScript ist auf den nicht strikten Gleichheitsoperator (==) zurückzuführen. Dieser Operator führt eine sogenannte Typumwandlung durch, was bedeutet, dass er versucht, Werte in einen gemeinsamen Typ umzuwandeln, bevor er sie vergleicht. Dies kann zu überraschend unerwarteten und sehr schwer zu debuggenden Ergebnissen führen.

Zum Beispiel:

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

So etwas kann einen in der Entwicklung in den Wahnsinn treiben. Der ==-Operator vergleicht [] (ein leeres Array) mit ![] (was sich als falsch herausstellt, da [] als wahrer Wert betrachtet wird und ![] ihn in falsch umwandelt). Aufgrund der internen Zwangsregeln von JavaScript ist dies jedoch ein gültiges Ergebnis, auch wenn es auf den ersten Blick keinen Sinn ergibt.

Warum passiert das?

JavaScript konvertiert beide Seiten des Vergleichs vor dem Vergleich in einen gemeinsamen Typ. In diesem Fall wird das leere Array [] im Vergleich zum booleschen Wert von ![] falsch. Diese Art von Zwang ist ein klares Beispiel dafür, wie subtile und schwer erkennbare Fehler auftreten können.

Tipp: Verwenden Sie immer strikte Gleichheit

Um diese Probleme zu vermeiden, sollten Sie, wann immer möglich, strikte Gleichheit verwenden (===). Der Unterschied besteht darin, dass dieser -Operator keine Typerzwingung durchführt. Dies bedeutet, dass sowohl der Wert als auch der Typ der Variablen streng verglichen werden.

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
});

Weitere typische Beispiele

Hier sind einige häufigere Beispiele dafür, wie nicht strikte Gleichheit (==) problematisch sein kann:

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

Warum ist es wichtig, === zu verwenden?

  • Vorhersage und Zuverlässigkeit: Durch die Verwendung von === erhalten Sie vorhersehbarere Vergleiche, ohne Überraschungen oder Typkonvertierungen.
  • Vermeiden Sie schwer zu erkennende Fehler:Wenn Ihr Code größer und komplexer wird, kann es sehr schwierig sein, Fehler im Zusammenhang mit der Typerzwingung zu finden und zu debuggen.
  • Verbessern Sie die Lesbarkeit des Codes: Es ist für andere Entwickler (oder Sie selbst in Zukunft) einfacher, Ihren Code zu verstehen, wenn Sie explizite Vergleiche sehen, ohne die Verwirrung durch implizite Konvertierungen.

Das obige ist der detaillierte Inhalt vonBest Practices in modernem JavaScript – Teil 2. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn