FEInterview Prep

Velog

자바스크립트의 논리 할당 연산자: 간단한 문법, 큰 이점

||=, &&=, ??= 의 의미·단락 평가·falsy 함정. "기본값 설정에는 ??=, falsy 덮어쓰기에는 ||=" 규칙 한 문장으로 정리.

2025-09-04·5분 읽기
JavaScript
원문 보기 ↗

핵심 요약

정리:

연산자발동 조건의도
`a= b`
a &&= batruthytruthy 일 때만 업데이트
a ??= banull/undefined진짜 누락 일 때만 기본값

주의:

  • 옵셔널 체이닝 좌변 금지: user?.settings ||= {} → SyntaxError
  • &&= 는 truthy 게이트지만 결과값 으로 덮어씀(원본 유지 X)
  • ||=0/''/false 같은 의도된 값 파괴 위험
  • 우변은 단락 평가되어 side effect 도 절약(config.apiKey ||= fetchApiKey())

논리 할당 연산자는 "조건부 검사 + 할당" 의 단축형이며, 단락 평가로 오른쪽 표현식이 필요할 때만 평가된다(side effect 안전성). 핵심은 "falsy 인가, nullish 인가" 를 정확히 구분하는 것.

면접에서 let count = 0; count ||= 10 의 결과 같은 코너 케이스가 단골이다. ??= 는 "null/undefined 만" 잡는 반면 ||=0,'',false 까지 덮어쓰는 차이는 버그의 출처 가 된다. 한 번에 정리하면 평생 안 헷갈린다.

학습 포인트

면접 답변으로 연결할 학습 포인트입니다.

`||=` vs `??=` — falsy 와 nullish 의 결정적 차이

let count = 0;
count ||= 10;   // count === 10 (0 은 falsy)
count = 0;
count ??= 10;   // count === 0  (0 은 nullish 아님)

사용자가 "의도적으로 0 을 넣었나, 그냥 비어 있나" 를 구분해야 하는 곳에서는 반드시 ??=.

falsynullish||=??=
자주 하는 오해

"기본값은 ||= 로" 라고 외워서 count/enabled 같은 boolean·숫자 값을 의도치 않게 덮어쓰는 것.

`&&=` 는 "truthy 게이트" 이지만 결과값으로 _덮어쓴다_

let isEnabled = true;
isEnabled &&= false;
console.log(isEnabled); // false

원본 truthy 가 게이트일 뿐, 새 값은 우변 결과(falsy 가능). 이 점에서 if (cond) x = y 와 의미가 같다는 것을 명심.

&&=truthy gateassignment
자주 하는 오해

"truthy 면 그대로 둔다" 라고 오해. 실제는 우변 평가 결과로 대체 된다.

단락 평가가 `apiKey ||= fetchApiKey()` 같은 비싼 호출을 보호한다

config.apiKey ||= fetchApiKey(); // apiKey 가 falsy 일 때만 fetch 호출
user?.settings ||= {};            // ❌ SyntaxError

옵셔널 체이닝의 결과는 참조가 아니라 값 이라 좌변에 올 수 없다. 할당 대상은 항상 참조(변수/속성) 여야 한다.

short-circuitoptional chainingside effect
자주 하는 오해

obj?.x ||= y 로 SyntaxError 만나는 것. 우회는 if (obj) obj.x ||= y 또는 obj && (obj.x ||= y).

읽는 순서

  1. 1이론

    MDN Logical assignment 3개 페이지를 훑고, 각 연산자 발동 조건과 "같은 의미의 if 문" 을 표로 정리.

  2. 2구현

    count = 0, name = '', enabled = false 3가지 시나리오에서 ||= vs ??= 결과 차이를 콘솔로 확인.

  3. 3실무

    현재 프로젝트의 value || default / value ?? default 패턴을 grep 해, falsy 보존이 필요한가 기준으로 분류 후 일괄 치환 가능한지 평가.

  4. 4설명

    "||=/??=/&&= 의 차이를 코드 예시 1개씩으로 5분 안에" 동료에게 설명. 함정 케이스(0 보존, &&= 의 결과 덮어쓰기) 도 포함.

면접 연결 질문

easy`count ||= 10` 과 `count ??= 10` 이 다르게 동작하는 한 케이스를 코드로 보여 주세요.
힌트

[좋은 답변] let count = 0 으로 시작해 ||= 는 10 으로 덮어쓰지만 ??= 는 0 을 유지. 의도된 0 을 보존하려면 ??= 가 안전.

medium`&&=` 가 _원본 truthy 값을 보존하지 않는다_ 는 점이 왜 함정이 될 수 있나요?
힌트

[좋은 답변] isLoggedIn &&= checkPermissions() 에서 checkPermissions 가 false 를 반환하면 isLoggedIn 이 false 로 바뀐다. 즉 권한 검사 후 로그인 자체가 무효 가 되는 부수효과. 의미를 명시하려면 if (isLoggedIn) hasPermission = checkPermissions() 가 더 명확.

medium옵셔널 체이닝과 논리 할당 연산자를 함께 쓸 수 없는 이유와 우회 방법은?
힌트

[좋은 답변] 좌변은 참조 여야 하는데 obj?.x 을 반환. 우회: if (obj) obj.x ||= y 또는 (obj ??= {}).x ||= y.

자기 점검

`||=` 가 적합한 케이스와 부적합한 케이스를 한 줄씩.
falsy0''default
자주 하는 오해

"기본값엔 항상 ||=" — 0/''/false 가 의미 있는 값일 때 깨진다.

Redux 같은 불변 상태에서 논리 할당을 직접 쓰면 안 되는 이유?
mutationimmutabilityhistory
자주 하는 오해

"문법이라 안전" — 실제로는 원본 객체를 직접 변경 하므로 history/time-travel 디버깅이 깨진다.