==와 ===의 차이는 무엇인가요?

면접용

=====는 자바스크립트에서 사용되는 비교 연산자입니다. 둘 다 값이 동일한지 비교하는데 사용되지만 비교하는 방식과 엄격성에서 차이가 있습니다.

== 연산자는 값을 비교할 때 자동으로 타입 변환을 수행합니다. 따라서 타입이 다른 두 값을 비교할 때 값만 같아도 true를 반환합니다.

반면에 === 연산자는 타입 변환을 수행하지 않고 값과 타입을 모두 비교합니다. 비교하는 값의 타입과 값이 정확히 일치해야 true를 반환합니다.

=== 연산자는 더 엄격하므로 타입 변환에 의해 예상치 못한 결과를 발생시킬 가능성이 낮아 안전합니다. 따라서 비교 시 정확성이 중요한 상황에서는 === 연산자를 사용하는 것이 좋습니다.


개념설명

==란?

==는 동등연산자(Equal Operator)입니다. a == b 일때, 두 변수의 값만 비교하여 결과를 boolean으로 반환합니다.

값을 비교할 때 암묵적 타입 변환을 수행하기 때문에, 두 변수의 타입이 달라도 비교가 가능합니다. 이는 자바스트립트가 런타임에 변수 값 할당 시 해당 값의 타입에 따라 변수 타입도 결정되는 동적 타입 언어이기 때문입니다. 따라서 여러 유형의 값을 함께 사용하기 위해 암묵적 타입 변환을 수행합니다.

동등연산자의 기능에 대해 조금 더 살펴보겠습니다.

1. 두 피연산자가 동일한 타입일 때 다음과 같은 상황에서 true를 반환합니다.

  • 객체: 두 피연산자가 동일한 객체를 참조할 때

    const obj1 = { key: "value" };
    const obj2 = obj1;
    
    console.log(obj1 === obj2); // true (동일한 객체를 참조)
    console.log({ key: "value" } === { key: "value" }); // false (다른 객체)
  • 문자열: 두 피연산자가 동일한 문자를 동일한 순서로 가질 때

    console.log("hello" === "hello"); // true
    console.log("hello" === "world"); // false
  • 숫자: 두 피연산자가 동일한 값을 가질 때

    • +0과 -0은 동일한 값입니다.

    • 두 피연산자가 모두 NaN이라면 false를 반환합니다.

    console.log(42 === 42); // true
    console.log(+0 === -0); // true (JavaScript에서 동일하게 간주)
    console.log(NaN === NaN); // false (특수 규칙)
  • boolean: 두 피연산자가 모두 true이거나 false일 때

    console.log(true === true); // true
    console.log(false === false); // true
    console.log(true === false); // false
  • BigInt: 두 피연산자가 동일한 값을 가질 때

    const big1 = 123n;
    const big2 = 123n;
    
    console.log(big1 === big2); // true
  • 심볼: 두 피연산자가 동일한 심볼을 참조할 때

    const sym1 = Symbol("id");
    const sym2 = sym1;
    const sym3 = Symbol("id");
    
    console.log(sym1 === sym2); // true (동일한 심볼)
    console.log(sym1 === sym3); // false (다른 심볼, 같은 설명)

2. 한 피연산자가 null/undefined인 경우, 다른 하나도 null/undefined여야 true를 반환합니다.

console.log(null == undefined); // true
console.log(null == 0); // false
console.log(undefined == false); // false

3. 한 피연산자가 객체이고 다른 하나가 원시 타입일 경우 객체를 원시 타입으로 변환합니다.

const obj = { valueOf: () => 42 };

console.log(obj == 42); // true (객체가 숫자로 변환됨)

4. 다음의 경우에서 두 연산자를 모두 원시 타입으로 변환합니다.

  • 원시 타입이란?

    • 불변성: 변경할 수 없고, 값이 변경될 경우 새롭게 메모리에 저장되는 데이터 타입

    • 값에 의한 복사: 원시 값을 다른 변수에 할당하면 두 변수는 서로 독립적으로 값을 가짐

    • 숫자, 문자열, 불리언, undefined, null, symbol, BigInt

  • 하나의 피연산자가 심볼이고 다른 하나가 심볼이 아닌 경우, false를 반환합니다.

    const sym = Symbol("id");
    
    console.log(sym == "id"); // false
    console.log(sym == Symbol("id")); // false
  • 하나의 피연산자가 불리언이고 다른 하나가 불리언이 아닌 경우, 불리언을 숫자로 변환합니다.

    console.log(true == 1); // true (true가 숫자 1로 변환)
    console.log(false == 0); // true (false가 숫자 0으로 변환)
  • 숫자와 문자열: 문자열을 숫자로 변환합니다.

    console.log(42 == "42"); // true (문자열 "42"가 숫자 42로 변환)
  • 숫자와 BigInt: 숫자 값으로 비교합니다.

    console.log(42n == 42); // true (BigInt와 숫자를 비교)
  • 문자열과 BigInt: 문자열을 BigInt로 변환합니다.

    console.log(42n == "42"); // true (문자열 "42"가 BigInt로 변환)

===란?

===는 엄격한 동등 연산자(Strict Equal Operator)입니다. 비교하는 변수들의 값과 타입을 모두 비교합니다. 타입 변환을 수행하지 않기 때문에 비교하는 두 변수의 값과 타입이 정확히 일치하는지 확인할 수 있습니다.

== 연산자와 비교했을 때, 1번의 경우를 제외한 모든 경우에서 false를 반환합니다.

그럼 어떤 것을 사용해야 할까?

기본적으로 변수나 값을 비교할 때는 ‘===’ 연산자를 사용하고, 자료형이 다를 경우에는 직접 자료형을 변환하는 쪽이 좋습니다.

특히 타입스크립트처럼 타입 안정성을 중요시하는 언어에서는 ===를 사용하는 것을 권장하고 있습니다.

==는 예외적인 경우에만 사용합니다.

ex) null == undefined 비교


참고 문서

MDN - 동등연산자(==)

iliakan - 형변환

iliakan - 객체를 원시형으로 변환하기

Last updated