Modern JavaScript

변수와 스코프 (let, const)

var는 버그를 유발하기 쉬워 더 이상 사용하지 않음. 혹 동료가 var를 사용하고 있다면 거침없는 하이킥으로..

const maxPoints = 100; // 변경 불가
let currentScore = 0;  // 변경 가능
currentScore += 10;

객체 초기화 단축 성격 (Property Shorthand)

const name = 'Sora';
const age = 28;

// 과거 방식
const user = { name: name, age: age };

// 최신 방식 (똑같이 동작합니다)
const user = { name, age };

구조를 분해해서 할당 (구조분해할당, Destructuring Assignment)

const user = { name: 'Alice', age: 30, city: 'Seoul' };

// 객체 구조 분해
const { name, age } = user;
console.log(name, age); // Alice 30

const { name: name2, ...sss } = user;
console.log(name2, sss); // Alice { age: 30, city: 'Seoul' }

// 다른 이름으로 할당하거나 기본값 설정도 가능
const { name: fullName, email = 'noemail@example.com' } = user;
console.log(fullName, email); // Alice noemail@example.com

// 배열 구조 분해
const colors = ['red', 'green', 'blue'];
const [first, second, third] = colors;
console.log(first, second, third); // red green blue

화살표 함수 (Arrow Functions)

화살표 함수는 this에 대한 유지력이 발생

// 기존 방식
function add(a, b) {
  return a + b;
}

// 화살표 함수 (최신)
const add = (a, b) => a + b;

구성 요소를 펼쳐 사용하는 문법 (스프레드 문법, Spread Syntax)

/* 배열 결합 및 복사에서의 예 */

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];

// 배열 결합
const combinedArr = [...arr1, ...arr2];
console.log(combinedArr); // [1, 2, 3, 4, 5, 6]

// 배열 복사 (얕은 복사)
const copiedArr = [...arr1];
console.log(copiedArr); // [1, 2, 3]

/* 객체 병합 및 복사에서의 예 */

const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };

// 객체 병합
const combinedObj = { ...obj1, ...obj2 };
console.log(combinedObj); // { a: 1, b: 2, c: 3, d: 4 }

// 객체 복사 (얕은 복사)
const copiedObj = { ...obj1 };
console.log(copiedObj); // { a: 1, b: 2 }

/* 함수 인자 전달에서의 예 */

function sum(a, b, c) {
  return a + b + c;
}

const numbers = [1, 2, 3];
console.log(sum(...numbers)); // 6 (배열 요소를 개별 인자로 펼쳐서 전달)

// 나머지: 모으기
function sum2(first, ...rest) {
  return rest.reduce((acc, v) => acc + v, first);
}

console.log(sum2(1, 2, 3, 4)); // 출력 : 10

null 또는 undefine이 아닐 경우에 대한 선택적 체이닝(선택적 체이닝, Optional Chaining)

const user = {
  name: 'Dave',
  address: {
    street: '123 Main St',
    city: 'Busan'
  },
  // phone: '010-1234-5678' // phone 속성이 없을 수 있음
};

// 기존 방식 (에러 방지)
let city = user.address && user.address.city;
console.log(city); // Busan

let zipCode;
if (user.address && user.address.zipCode) {
  zipCode = user.address.zipCode;
}
console.log(zipCode); // undefined

// 선택적 체이닝
const userCity = user.address?.city;
console.log(userCity); // Busan

const userPhone = user.phone?.number; // user.phone이 undefined이므로 userPhone은 undefined
console.log(userPhone); // undefined

const userStreet = user.address?.street;
console.log(userStreet); // 123 Main St

// 배열 요소에도 적용 가능
const arr = [{ value: 10 }];
const firstValue = arr?.[0]?.value;
console.log(firstValue); // 10

const emptyArr = [];
const nonExistentValue = emptyArr?.[0]?.value;
console.log(nonExistentValue); // undefined

// 매서드도 가능함
console.log?.("....");

진짜 null 또는 undefine에 대한 선택 연산자 (Nullish 병합 연산자, Nullish Coalescing Operator)

const userInput = null;
const defaultValue = 'default value';

// || 연산자 (Falsy 값도 걸러냄)
const resultOr = userInput || defaultValue;
console.log(resultOr); // default value

const zeroValue = 0;
const resultOrZero = zeroValue || defaultValue;
console.log(resultOrZero); // default value (0도 Falsy로 간주하여 default value가 할당됨)

// ?? 연산자 (null 또는 undefined만 걸러냄)
const resultNullish = userInput ?? defaultValue;
console.log(resultNullish); // default value

const zeroValueNullish = 0;
const resultNullishZero = zeroValueNullish ?? defaultValue;
console.log(resultNullishZero); // 0 (0은 유효한 값으로 간주됨)

const emptyString = '';
const resultNullishEmptyString = emptyString ?? defaultValue;
console.log(resultNullishEmptyString); // ''

비동기 처리 ( async / await )

async function fetchData() {
  try {
    const res = await fetch("https://api.example.com/data");
    const data = await res.json();
    console.log(data);
  } catch (err) {
    console.error(err);
  }
}

최신 배열 / 객체 메서

// 배열
[1, 2, 3].at(-1); // 3 (뒤에서 인덱스)
[1, [2, [3]]].flat(Infinity); // [1, 2, 3]
[1, 2, 3].flatMap(x => [x, x * 2]); // [1,2, 2,4, 3,6]
// 객체
Object.entries({ a: 1, b: 2 }); // [["a",1], ["b",2]]
Object.fromEntries([["a", 1]]); // { a: 1 }
Object.hasOwn(obj, "key"); // true/false (ES2022)

기존 .sort()나 .reverse()는 원본 배열 자체를 바꾸어 버려서 버그를 자주 유발했습니다. 최신 메서드는 원본은 그대로 두고, 정렬된 ‘새로운 배열’을 반환합니다.

const numbers = [3, 1, 4];
const sorted = numbers.toSorted();

console.log(numbers); // [3, 1, 4] (원본 유지!)
console.log(sorted);  // [1, 3, 4] (새 배열)

논리 할당 연산자

a ||= "기본값"; // a가 falsy면 할당
a &&= "새값"; // a가 truthy면 할당
a ??= "기본값"; // a가 null/undefined면(truthy와 다름) 할당

Promise 관련

// 모두 성공해야 통과
await Promise.all([p1, p2, p3]);
// 하나라도 완료되면 통과
await Promise.race([p1, p2]);
// 성공/실패 관계없이 전부 기다림
await Promise.allSettled([p1, p2]);
// 하나라도 성공하면 통과
await Promise.any([p1, p2])

for…of / for…in

for (const item of [1, 2, 3]) { } // 값 순회
for (const key in { a: 1, b: 2 }) { } // 키 순회

최상위 await (Top-level await)

예전에는 await 키워드를 쓰려면 무조건 async 함수 내부에서만 감싸서 사용해야 했습니다. 이제는 모듈 시스템(import/export를 쓰는 환경) 파일의 가장 바깥쪽(Top-level)에서도 async 함수 없이 바로 await를 쓸 수 있습니다.

const response = await fetch('https://api.example.com/config');
export const config = await response.json();

	

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다