자바스크립트의 논리 연산자는 단순히 true/false를 반환하는 게 아닙니다. 단축 평가(short-circuit evaluation) 를 이해하면 코드를 훨씬 간결하게 쓸 수 있고, ???.는 모던 자바스크립트의 필수 문법입니다.

단축 평가 (Short-Circuit Evaluation)

&& (논리 AND)

&&는 첫 번째 falsy 값을 반환하고, 모두 truthy면 마지막 값을 반환합니다.

JS
// falsy 값을 만나면 즉시 반환
console.log(0 && "hello");        // 0
console.log("" && "hello");       // ""
console.log(null && "hello");     // null

// 모두 truthy면 마지막 값 반환
console.log("a" && "b" && "c");   // "c"

// 실전: 조건부 실행
const isAdmin = true;
isAdmin && showAdminPanel(); // isAdmin이 true일 때만 실행

|| (논리 OR)

||는 첫 번째 truthy 값을 반환하고, 모두 falsy면 마지막 값을 반환합니다.

JS
// truthy 값을 만나면 즉시 반환
console.log("hello" || "default"); // "hello"
console.log(0 || "default");       // "default"

// 모두 falsy면 마지막 값 반환
console.log(0 || "" || null);      // null

// 실전: 기본값 설정
const name = userInput || "익명";

|| 의 함정

JS
// 문제: 0과 빈 문자열도 falsy로 취급됨
const count = 0;
const result = count || 10;
console.log(result); // 10 — 0이 유효한 값인데 무시됨!

const text = "";
const display = text || "기본 텍스트";
console.log(display); // "기본 텍스트" — 빈 문자열이 의도된 값일 수 있음

이 문제를 해결하기 위해 Nullish Coalescing 연산자 가 등장했습니다.

?? (Nullish Coalescing)

??는 왼쪽 값이 null 또는 undefined일 때만 오른쪽 값을 반환합니다.

JS
// null과 undefined만 걸러냄
console.log(0 ?? 10);         // 0 — 0은 null/undefined가 아님
console.log("" ?? "기본");    // "" — 빈 문자열도 유효
console.log(false ?? true);   // false — false도 유효
console.log(null ?? "기본");  // "기본"
console.log(undefined ?? 10); // 10

|| vs ?? 비교

JS
const config = { timeout: 0, retries: null };

// || 사용 — 0이 무시됨
config.timeout || 3000;  // 3000 (의도치 않음)

// ?? 사용 — 0은 유효한 값
config.timeout ?? 3000;  // 0 (정확한 동작)
config.retries ?? 3;     // 3 (null이니까 기본값)

면접에서 "||와 ??의 차이"를 물어보면, ||는 **falsy 체크 **, ??nullish 체크 라고 답하면 됩니다.

?. (Optional Chaining)

중첩 객체의 프로퍼티에 안전하게 접근합니다.

JS
const user = {
  name: "정훈",
  address: {
    city: "서울",
  },
};

// 기존 방식 — 장황함
const zipCode = user && user.address && user.address.zipCode;

// Optional Chaining — 간결
const zipCode2 = user?.address?.zipCode;
console.log(zipCode2); // undefined (에러 없이)

다양한 활용

JS
// 메서드 호출
const result = user.getName?.(); // getName이 없으면 undefined

// 배열 접근
const first = arr?.[0]; // arr이 null/undefined면 undefined

// 동적 프로퍼티
const value = obj?.[dynamicKey];

// 함수 호출
callback?.(); // callback이 있을 때만 실행

??와 ?. 조합

JS
// API 응답에서 안전하게 값 추출 + 기본값 설정
const response = {
  data: {
    user: null,
  },
};

const userName = response?.data?.user?.name ?? "익명";
console.log(userName); // "익명"

??= (Nullish 할당)

JS
let config = { timeout: null, retries: 3 };

// null이면 할당
config.timeout ??= 5000;
console.log(config.timeout); // 5000

// null/undefined가 아니면 유지
config.retries ??= 10;
console.log(config.retries); // 3

// ||= 도 있음 (falsy 할당)
let count = 0;
count ||= 10;
console.log(count); // 10 — 0이 falsy라서 할당됨

count = 0;
count ??= 10;
console.log(count); // 0 — 0은 nullish가 아님

falsy 값 총정리

JS
// 자바스크립트의 falsy 값 (7개)
if (!false) console.log("false");
if (!0) console.log("0");
if (!(-0)) console.log("-0");
if (!"") console.log("빈 문자열");
if (!null) console.log("null");
if (!undefined) console.log("undefined");
if (!NaN) console.log("NaN");

// 나머지는 전부 truthy
if ({}) console.log("빈 객체도 truthy");   // truthy
if ([]) console.log("빈 배열도 truthy");   // truthy
if ("0") console.log("문자열 0도 truthy"); // truthy

빈 객체 {}와 빈 배열 []이 truthy라는 점은 면접에서 자주 출제됩니다.

실전 패턴 모음

JS
// 1. 조건부 프로퍼티 추가
const user = {
  name: "정훈",
  ...(isAdmin && { role: "admin" }),
};

// 2. 환경 변수 기본값
const port = process.env.PORT ?? 3000;

// 3. API 응답 안전 처리
const items = response?.data?.items ?? [];

// 4. 메서드 존재 확인 후 호출
element?.addEventListener?.("click", handler);

**기억하기 **: ||는 falsy 전부를 걸러내고, ??는 null과 undefined만 걸러냅니다. ?.는 중첩 접근의 안전 장치입니다. 이 세 가지를 조합하면 방어적 코드를 간결하게 작성할 수 있습니다.

댓글 로딩 중...