>웹 프론트엔드 >JS 튜토리얼 >최신 JavaScript의 모범 사례 - 2부

최신 JavaScript의 모범 사례 - 2부

Patricia Arquette
Patricia Arquette원래의
2024-12-08 16:09:12737검색

Mejores Prácticas en JavaScript Moderno - Parte 2

이 기사의 첫 번째 부분에서는 최신 JavaScript의 기본 사항과 더 깨끗하고 효율적인 코드 작성을 시작하기 위한 몇 가지 필수 모범 사례를 살펴보았습니다. 하지만 개발자로서 우리는 항상 배우고 개선할 것이 더 많다는 것을 알고 있습니다.

8. 선택적 연결(?.)

객체나 중첩 구조로 작업할 때 속성에 액세스하기 전에 속성이 존재하는지 확인해야 할 때가 있습니다. 선택적 연결 연산자(?.)는 이 작업을 단순화하여 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에 액세스하려고 할 때 오류를 방지할 수 있습니다.

코드가 어떻게 향상되나요?

  • null 또는 정의되지 않은 속성에 대한 액세스 오류를 방지하세요.
  • 코드를 단순화하여 보안 검사를 더욱 깔끔하고 읽기 쉽게 만듭니다.
  • 불확실하거나 불완전한 데이터로 작업할 수 있습니다. 이는 API 또는 데이터베이스의 응답으로 작업할 때 매우 일반적입니다.

보너스: 함수를 사용한 선택적 연결

선택적 체이닝은 함수와 함께 사용할 수도 있는데, 이는 객체에 정의되지 않은 함수가 있을 때 매우 유용합니다.

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

여기서 getAge 함수는 정의되지 않았지만(Null임) 오류를 발생시키지 않고 단지 정의되지 않은 값을 반환합니다.

9. 비동기 처리를 위해 async/await를 사용하세요

API에서 데이터를 가져오거나 파일을 읽는 등 JavaScript에서 비동기 작업을 수행할 때 async/await 구문이 가장 좋은 친구가 될 수 있습니다. .then() 및 .catch()와 함께 Promise를 사용하는 대신 async/await를 사용하면 동기 코드를 작성하는 방법과 유사하게 더 깔끔하고 읽기 쉬운 방식으로 비동기 코드를 작성할 수 있습니다.

비동기/대기를 사용하는 이유는 무엇입니까?

  • 단순함과 가독성: 읽고 유지 관리하기 복잡해질 수 있는 "약속 체인"을 피하세요.
  • 보다 직관적인 오류 처리: try/catch를 사용하여 오류를 처리하는 것이 .catch()를 사용하는 것보다 훨씬 명확합니다.
  • 보다 정밀한 제어: 함수 내 어디에서나 Wait를 사용할 수 있으므로 더 복잡한 비동기 흐름을 더 쉽게 제어할 수 있습니다.

기본 사용 예:

데이터를 반환하는 API로 작업한다고 가정해 보겠습니다. .then() 대신 async/await를 사용하면 흐름을 훨씬 쉽게 따라갈 수 있습니다.

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

실제 예: API에서 데이터를 가져와 UI에 표시

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를 사용한 반복

이러한 메소드를 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"]

이 접근 방식은 특히 크거나 복잡한 개체로 작업하는 경우 더욱 깔끔하고 읽기 쉽습니다.

11. 기본이 아닌 키에는 맵을 사용하세요

문자열이나 기호가 아닌 키에 값을 연결해야 하는 경우 Map을 사용하세요. 더욱 강력하고 키의 유형과 순서를 유지합니다.

예:

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

12. 고유 키에 기호를 사용하세요.

기호는 고유하고 변경할 수 없는 키를 생성할 수 있는 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 결합

Symbol을 Object.defineProperty와 함께 사용하면 보다 제어된 방식으로 객체에 속성을 추가하여 속성을 열거할 수 없도록 할 수도 있습니다.

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

이 예에서 secretKey는 객체의 키 열거에 표시되지 않으므로 실수로 액세스하거나 수정해서는 안 되는 "개인" 값에 이상적입니다.

고려사항:

  • 기호는 특히 타사 라이브러리나 API로 작업할 때 속성 이름 충돌을 피하는 데 유용합니다.
  • 기호는 엄밀히 말하면 "비공개"는 아니지만 일반적으로 액세스할 수 없다는 사실은 데이터 무결성을 보호하는 데 도움이 됩니다.
  • 기호는 JSON으로 직렬화할 수 없으므로 데이터를 전송해야 하는 경우 기호 속성을 적절하게 처리해야 합니다.

13. JSON과 큰 숫자에 주의하세요

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를 처리하지 않으므로 숫자를 직렬화할 때 숫자를 문자열로 변환한 다음 역직렬화할 때 다시 변환해야 합니다.

다음은 이를 수행할 수 있는 방법의 예입니다.

BigInt 및 JSON.stringify를 사용한 솔루션

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나 시스템을 사용하여 작업할 때 특히 중요합니다. 숫자를 잘못 해석하면 애플리케이션에 오류가 발생하거나 더 심각한 경우 금융 거래나 데이터베이스의 고유 식별자 처리와 같이 중요한 데이터에 오류가 발생할 수 있습니다.

기억하세요: 정밀도 제한을 무시하지 마세요. 작은 디테일처럼 보일 수도 있지만 예상치 못한 비용과 비용으로 인해 애플리케이션이 실패할 수 있는 영역입니다.

14. if 문의 표현식을 명시적으로 처리하세요.

JavaScript에서 if 문은 표현식을 암시적으로 "참" 또는 "거짓" 값으로 변환하는데, 이 동작을 고려하지 않으면 예상치 못한 결과가 발생할 수 있습니다. 이 동작은 때때로 유용할 수 있지만 미묘한 오류를 방지하고 코드 가독성을 높이려면 비교 시 명시적으로 하는 것이 좋습니다.

"진실" 또는 "거짓"은 무엇을 의미하나요?

  • "Falsy"는 조건식에서 평가할 때 false와 동일하다고 간주되는 값을 의미합니다. 예: 0, ""(빈 문자열), null, 정의되지 않음, NaN.
  • "Truthy"는 falsy가 아닌 모든 값, 즉 위에 해당되지 않는 모든 값을 의미합니다. 예: 0이 아닌 모든 숫자, 비어 있지 않은 문자열, 객체 등

암시적 예(예상치 못한 결과가 발생할 수 있음)

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에서 잘못된 값의 암시적 동작을 기억하지 않고도 다른 사람(또는 미래의 자신)이 논리를 빠르게 이해할 수 있으므로 유지 관리성이 향상됩니다.

15. 가능하다면 엄격한 동등성(===)을 사용하세요.

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.