[JavaScript] ==와 === 의 차이, 동등비교와 일치비교

진세오·2025년 7월 5일

동등연산자

    자바스크립트에서는 대상을 비교하는 연산자로 ==(이중등호, 동등연산자, 느슨한 동등)===(삼중등호, 일치연산자, 엄격한 동등)가 존재합니다. 두 연산자 모두 값을 비교한다는 공통점이 있지만, 일치연산자는 값과 타입을 같이 확인한다는 차이점이 있습니다.

예시

//동등비교
console.log("0" == 0) // true
console.log('' == false) // true
console.log('12' == 12) // true
console.log(123 == 12) // false

//일치비교
console.log("0" === 0) // false
console.log('' === false) // false
console.log('12' === 12) // false
console.log('12' === '12') // true

    위의 예시처럼 동등비교는 값만을 비교하기때문에 falsy값도 false와 동일하다고 보고, 일치비교는 두 대상의 값과 타입이 일치해야 동일하다고 판단합니다.

=== : 엄격한 동등(strict equality)

    삼중등호는 일치연산자 라고도 합니다. 두 대상을 비교할때, 값 뿐만 아니라 타입도 비교하고 대상의 값과 타입이 같을때 true를 반환합니다. 숫자를 제외한 모든 값에 "하나의 대상(값)은 자신과 같다"라는 의미가 적용됩니다. 다만 NaN타입 은 예외가 되어 NaN === NaNfalse가 됩니다. 아래의 표를 통해 엄격한 동등비교에서 어떻게 비교할때 true가 나오는지 확인할 수 있습니다.

https://dorey.github.io/JavaScript-Equality-Table/

== : 느슨한 동등(loose equality)

    이중 등호는 동등연산자라고도 합니다. 두 대상의 값을 비교하며, 비교할 때 암시적 형변환이 발생할 수 있습니다. 느슨한 동등이 수행되는 동작은 다음과 같습니다.

  1. 피연산자(비교가 되는 두 대상)의 타입이 동일한 경우 다음과 같이 비교됩니다.

    • Object: 두 피연산자가 동일한 객체를 참조하는 경우에만 true를 반환합니다.
    • String: 두 피연산자가 동일한 순서로 동일한 문자를 갖는 경우에만 true를 반환합니다.
    • Number: 두 피연산자의 값이 같은 경우에만 true를 반환합니다. +0과 -0은 같은 값으로 취급합니다. 피연산자 중 하나가 NaN 이면 false를 반환합니다. 따라서 NaN은 결코 NaN과 같지 않습니다.
    • Boolean: 피연산자가 둘 다 true이거나 둘 다 false인 경우에만 true를 반환합니다.
    • BigInt: 두 피연산자가 동일한 값인 경우에만 true를 반환합니다.
    • Symbol: 두 피연산자가 동일한 symbol을 참조하는 경우에만 true를 반환합니다.
  2. 피연산자 중 하나가 null or undefined인 경우 다른 피연산자도 null or undefined 이면 true를 반환합니다. 두 개를 제외한 다른 타입일 경우 false를 반환합니다.

  3. 피연산자 중 하나가 Object이고 다른 하나가 원시 값(Primitive values)인 경우 Object원시 값으로 변환합니다.

  4. 이 단계에서 두 피연산자는 원시 값(String, Number, Boolean, Symbol, BigInt 중 하나)로 변환됩니다. 나머지 변환은 사항별로 수행됩니다.

아래의 표를 통해 느슨한 동등비교에서 어떻게 비교할때 true가 나오는지 확인할 수 있습니다.

https://dorey.github.io/JavaScript-Equality-Table/

원시타입으로 변환

    원시값으로 변환되는 기준은 ECMAScript 명세를 따라서 이루어집니다.

  1. If SameType(x, y) is true, then
    a. Return IsStrictlyEqual(x, y).
  2. If x is null and y is undefined, return true.
  3. If x is undefined and y is null, return true.
  4. NOTE: This step is replaced in section B.3.6.2.
  5. If x is a Number and y is a String, return ! IsLooselyEqual(x, ! ToNumber(y)).
  6. If x is a String and y is a Number, return ! IsLooselyEqual(! ToNumber(x), y).
  7. If x is a BigInt and y is a String, then
    a. Let n be StringToBigInt(y).
    b. If n is undefined, return false.
    c. Return ! IsLooselyEqual(x, n).
  8. If x is a String and y is a BigInt, return ! IsLooselyEqual(y, x).
  9. If x is a Boolean, return ! IsLooselyEqual(! ToNumber(x), y).
  10. If y is a Boolean, return ! IsLooselyEqual(x, ! ToNumber(y)).
  11. If x is either a String, a Number, a BigInt, or a Symbol and y is an Object, return ! IsLooselyEqual(x, ? ToPrimitive(y)).
  12. If x is an Object and y is either a String, a Number, a BigInt, or a Symbol, return ! IsLooselyEqual(? ToPrimitive(x), y).
  13. If x is a BigInt and y is a Number, or if x is a Number and y is a BigInt, then
    a. If x is not finite or y is not finite, return false.
    b. If ℝ(x) = ℝ(y), return true; otherwise return false.
  14. Return false.

    원시타입으로 변환하는 함수들은 ToPrimitive, ToBoolean, ToNumeric, ToNumber 등으로 ToX(변환하려는 원시타입)의 함수가 존재합니다. 따라서 위의 순서대로 논리연산을 거치며 비교하려는 대상이 어떤 타입이냐에 따라 형변환 함수가 실행됩니다.



둘 중 어떤것을 사용할 것인가

    일치연산자(===)를 더 권장하고 있습니다. 이유는 암시적 형변환을 막고, 코드가 작성된 의도대로 동작하게 하기 위해서 입니다. 프로그램의 안정성 향상 및 동일한 결과를 보장하기 위해서 동등연산자(==)는 지양하는 것이 좋습니다.


참고 사이트

0개의 댓글