이 기사의 첫 번째 부분에서는 최신 JavaScript의 기본 사항과 더 깨끗하고 효율적인 코드 작성을 시작하기 위한 몇 가지 필수 모범 사례를 살펴보았습니다. 하지만 개발자로서 우리는 항상 배우고 개선할 것이 더 많다는 것을 알고 있습니다.
객체나 중첩 구조로 작업할 때 속성에 액세스하기 전에 속성이 존재하는지 확인해야 할 때가 있습니다. 선택적 연결 연산자(?.)는 이 작업을 단순화하여 null 또는 정의되지 않은 값의 속성 액세스 오류를 방지하는 강력한 도구입니다.
복잡한 개체 구조가 있고 그 안에 특정 속성이 있는지 확실하지 않다고 상상해 보세요. 선택적 연결이 없으면 각 단계에서 수동으로 확인해야 하므로 코드가 길어지고 가독성이 낮아질 수 있습니다. ?. 연산자를 사용하면 속성에 안전하게 액세스할 수 있으며 중간 속성이 존재하지 않는 경우 정의되지 않은 상태가 됩니다.
const producto = {}; const impuesto = producto?.precio?.impuesto; console.log(impuesto); // undefined
이 경우 제품에 가격 속성이 없으므로 옵셔널 체이닝은 오류가 발생하는 대신 undefound를 반환합니다.
속성이 서로 다른 제품 목록이 있고 그 중 일부는 비어 있거나 정의되지 않은 경우를 상상해 보세요.
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에서 사용자 정보를 표시해야 하는 웹페이지가 있다고 상상해 보세요. 다음은 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
가장 다양한 방법입니다. 배열의 배열을 반환합니다. 각 하위 배열에는 키와 해당 값이 포함되어 있습니다. 이는 단일 작업으로 키와 값을 모두 사용하려는 경우에 유용합니다.
예:
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 키는 고유하며 코드의 다른 부분에서 또 다른 기호('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의 가장 혼란스러운 동작 중 하나는 엄격하지 않은 항등 연산자(==)에서 비롯됩니다. 이 연산자는 유형 강제라는 작업을 수행하는데, 이는 값을 비교하기 전에 값을 공통 유형으로 변환하려고 시도한다는 의미입니다. 이로 인해 놀랍게도 예상치 못한 결과가 나올 수 있으며 디버그하기가 매우 어렵습니다.
예:
const producto = {}; const impuesto = producto?.precio?.impuesto; console.log(impuesto); // undefined
개발할 때 미치게 만들 수 있는 종류의 일입니다. == 연산자는 [](빈 배열)을 ![]와 비교합니다([]는 참 값으로 간주되고 ![]는 이를 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!