この記事の最初の部分では、最新の JavaScript の基本と、よりクリーンで効率的なコードの作成を開始するための重要なベスト プラクティスについて説明しました。しかし、開発者として、私たちは常に学び、改善すべきことがたくさんあることを知っています。
オブジェクトやネストされた構造を操作するとき、アクセスする前にプロパティが存在するかどうかを確認する必要がある場合があります。 オプションの連鎖演算子 (?.) は、このタスクを簡素化し、null または未定義の値のプロパティ アクセス エラーを回避する強力なツールです。
複雑なオブジェクト構造があり、その中に特定のプロパティが存在するかどうかわからないと想像してください。オプションのチェーンを使用しない場合、各ステップで手動チェックを行う必要があり、コードが長くなり、読みにくくなる可能性があります。 ?. 演算子を使用すると、プロパティに安全にアクセスでき、中間プロパティが存在しない場合は unknown を取得できます。
const producto = {}; const impuesto = producto?.precio?.impuesto; console.log(impuesto); // undefined
この場合、製品には価格プロパティがないため、オプションのチェーンはエラーを生成するのではなく、未定義を返します。
さまざまなプロパティを持つ製品のリストがあり、その中には空または未定義のものもあると想像してください。
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 });
この例では、オプションのチェーンにより、詳細が null または存在しない場合でも、product.details.tax にアクセスしようとする際のエラーを回避できます。
オプションのチェーンは関数でも使用できます。これは、オブジェクトに定義されていない関数がある場合に非常に便利です。
const usuario = { nombre: 'Juan', obtenerEdad: null }; const edad = usuario.obtenerEdad?.(); console.log(edad); // undefined
ここでは、getAge 関数は未定義 (null です) ですが、エラーはスローされず、単に未定義を返します。
API からのデータの取得やファイルの読み取りなど、JavaScript で非同期操作を行う場合、async/await 構文が非常に便利です。 .then() や .catch() で Promise を使用する代わりに、async/await を使用すると、同期コードを記述する方法と同様に、よりクリーンで読みやすい方法で非同期コードを作成できます。
データを返す API を使用しているとします。 .then() の代わりに async/await を使用すると、フローがはるかにわかりやすくなります。
const producto = {}; const impuesto = producto?.precio?.impuesto; console.log(impuesto); // undefined
API からのユーザー情報を表示する必要がある Web ページがあると想像してください。以下は、async/await を使用してデータを取得し、インターフェースにレンダリングする方法の例です。
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 });
オブジェクトのプロパティのすべての値を含む配列を返します。キーを使わずに値だけが必要な場合に最適です。
例:
const usuario = { nombre: 'Juan', obtenerEdad: null }; const edad = usuario.obtenerEdad?.(); console.log(edad); // undefined
これは最も汎用性の高い方法です。配列の配列を返します。各サブ配列にはキーとそれに対応する値が含まれます。これは、1 回の操作でキーと値の両方を操作する場合に便利です。
例:
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); } }
これらのメソッドを for...of と組み合わせて、コードをさらにクリーンにできることをご存知ですか?以下は Object.entries():
を使用した例です。例:
// 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"]
このアプローチは、特に大きなオブジェクトや複雑なオブジェクトを扱う場合に、よりクリーンで読みやすくなります。
文字列や記号ではないキーに値を関連付ける必要がある場合は、Map を使用します。これはより堅牢であり、キーのタイプと順序を維持します。
例:
const producto = {}; const impuesto = producto?.precio?.impuesto; console.log(impuesto); // undefined
シンボルは、一意で不変のキーを作成できる JavaScript の機能で、値が誤って上書きされたりアクセスされたりしないようにする必要がある場合に強力なツールになります。シンボルは、Object.keys()、for...in、JSON.stringify() などのメソッドではアクセスできないため、プライベートまたは「非表示」の値に最適です。
テキスト文字列などのキーを使用してオブジェクトのプロパティを作成すると、それらは簡単に操作または上書きできます。ただし、シンボルを使用すると、同じ名前のシンボルを作成した場合でも、各キーが一意であることが保証されます。さらに、シンボルはオブジェクト プロパティの列挙には表示されません。
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 });
この例では、hiddenKey キーは一意であり、コードの別の部分で別の Symbol('hidden') を作成することもできますが、それは完全に異なるものであり、obj に格納されている値には影響しません。
Symbol を Object.defineProperty と併用して、より制御された方法でオブジェクトにプロパティを追加し、プロパティが列挙不可能であることを確認することもできます。
const usuario = { nombre: 'Juan', obtenerEdad: null }; const edad = usuario.obtenerEdad?.(); console.log(edad); // undefined
この例では、secretKey はオブジェクトのキー列挙に表示されないため、誤ってアクセスしたり変更したりしてはいけない「プライベート」値に最適です。
JavaScript では、大きな数値を処理するのが非常に困難になることがあります。 Number データ型には、整数を正確に表現する際に制限があります。安全な最大の整数値は 9007199254740991 (Number.MAX_SAFE_INTEGER とも呼ばれます) です。これより大きい数値を処理しようとすると、精度が失われ、アプリケーションでエラーが発生する可能性があります。
たとえば、外部 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); } }
ご覧のとおり、数値 9007199254740999 は、誤って 9007199254741000 に変換されます。これは、数値が一意の識別子や金額など、アプリケーションにとって重要な場合に問題となる可能性があります。
この問題を回避するにはどうすればよいですか?
シンプルで洗練された解決策は、ECMAScript 2020 で導入された BigInt データ型を使用することです。BigInt は、精度を失うことなく、はるかに大きな数値を処理できます。ただし、JSON は BigInt をネイティブに処理しないため、数値をシリアル化するときに数値を文字列に変換し、逆シリアル化するときに数値を文字列に変換する必要があります。
これを行う方法の例を次に示します。
const producto = {}; const impuesto = producto?.precio?.impuesto; console.log(impuesto); // undefined
このアプローチを使用すると、重要なデータを失うことなく、大きな数値の精度を維持できます。数値が再度必要になった場合は、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 });
BigInt を使用したくない場合、またはパフォーマンスが懸念される場合、別の戦略は、単純に大きな数値を JSON 内の文字列として扱うことです。これにより、コード内で変換を行う必要がある代わりに、精度の問題が回避されます。
例:
const usuario = { nombre: 'Juan', obtenerEdad: null }; const edad = usuario.obtenerEdad?.(); console.log(edad); // undefined
大きな数値を適切に処理することは、計算の精度にとって重要であるだけでなく、データの整合性を維持するためにも重要です。これは、完全には制御できないサードパーティ API やシステムを操作する場合に特に重要です。数値を誤解すると、アプリケーションで障害が発生したり、さらに悪いことに、金融取引やデータベースの一意の識別子の処理など、重大なデータでエラーが発生したりする可能性があります。
次の点に注意してください: 精度の制限を無視しないでください。細かいことのように思えるかもしれませんが、これはアプリケーションが予期せぬ形で失敗し、コストがかかる可能性がある領域です。
JavaScript では、if ステートメントは式を「真」または「偽」の値に暗黙的に変換します。この動作が考慮されていない場合、予期しない結果が生じる可能性があります。この動作は便利な場合もありますが、微妙なエラーを回避し、コードの可読性を向上させるために、比較では明示的に行うことをお勧めします。
const producto = {}; const impuesto = producto?.precio?.impuesto; console.log(impuesto); // undefined
上記の例では、0 は「偽」と見なされるため、条件は実行されません。ただし、より複雑な値を操作する場合、この動作を検出するのは困難になる可能性があります。
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 });
ヒント: 0、null、false、または "" など、false の可能性がある値を扱う場合は、比較を明示的に行うことが最善です。こうすることで、暗黙的な型強制動作によるものではなく、ロジックが期待どおりに実行されることを保証します。
null、空の配列 []、または空のオブジェクト {} を指定できるオブジェクトがあると考えてみましょう。次のようなことをすると:
const usuario = { nombre: 'Juan', obtenerEdad: null }; const edad = usuario.obtenerEdad?.(); console.log(edad); // undefined
[] (空の配列) は有効かつ真実なオブジェクトですが、動作を完全に理解していないと、将来混乱を招く可能性があります。暗黙的な強制に依存する代わりに、次のようなより明示的な比較を行うことが最善です。
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); } }
条件を明示的に定義すると、JavaScript の自動強制によって発生するエラーのリスクが軽減されます。このアプローチにより、コードがより明確になり、読みやすくなり、予測可能になります。さらに、他の人 (または将来の自分自身) が JavaScript の偽の値の暗黙的な動作を覚えていなくてもロジックをすぐに理解できるようになるため、保守性も向上します。
JavaScript の最も混乱を招く動作の 1 つは、非厳密な等価演算子 (==) に由来します。この演算子は、型強制 と呼ばれるものを実行します。これは、値を比較する前に共通の型に変換しようとすることを意味します。これにより、驚くほど予期しない結果が生成され、デバッグが非常に困難になる可能性があります。
例:
const producto = {}; const impuesto = producto?.precio?.impuesto; console.log(impuesto); // undefined
これは、開発中に気が狂ってしまうようなものです。 == 演算子は、[] (空の配列) と ![] を比較します ([] は true 値とみなされ、![] はそれを false に変換するため、これは false になります)。ただし、一見意味がわかりませんが、JavaScript の内部強制ルールにより、これは有効な結果です。
JavaScript は、比較の前に比較の両側を共通の型に変換します。この場合、空の配列 [] は、![] のブール値と比較すると false になります。このタイプの強制は、微妙で特定が難しいエラーがどのように発生するかを示す明らかな例です。
これらの問題を回避するには、可能な限り厳密な等価性 (===) を使用する必要があります。違いは、この 演算子が型強制 を実行しないことです。これは、変数の値と型の両方を厳密に比較することを意味します。
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 });
ここでは、非厳密な等価性 (==) がどのような問題を引き起こす可能性があるかを示す、より一般的な例をいくつか示します。
const usuario = { nombre: 'Juan', obtenerEdad: null }; const edad = usuario.obtenerEdad?.(); console.log(edad); // undefined
以上が最新の JavaScript のベスト プラクティス - パート 2の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。