동등 연산자

동등 연산자 (==)

동등(==) 연산자는 두 피연산자가 같은지 확인해 불리언 결과를 반환합니다. 엄격 동등 연산자와 달리, 서로 다른 타입의 피연산자를 변환하여 비교하려 시도합니다.

호환성: Baseline — 널리 사용 가능(Widely available). 이 기능은 잘 확립되어 있으며 많은 기기와 브라우저 버전에서 작동합니다. 2015년 7월부터 브라우저에서 사용할 수 있습니다.

출처: Equality (==)

본문

Try it

console.log(1 == 1);
// Expected output: true

console.log("hello" == "hello");
// Expected output: true

console.log("1" == 1);
// Expected output: true

console.log(0 == false);
// Expected output: true

구문 (Syntax)

x == y

설명 (Description)

동등 연산자(==!=)는 IsLooselyEqual 의미론을 제공합니다. 이는 대략 다음과 같이 요약할 수 있습니다.

피연산자들이 같은 타입이면 다음과 같이 비교됩니다.

  • Object: 두 피연산자가 같은 객체를 참조할 때만 true 반환.
  • String: 두 피연산자가 같은 순서로 같은 문자를 가질 때만 true 반환.
  • Number: 두 피연산자가 같은 값을 가질 때만 true 반환. +0-0은 같은 값으로 취급. 어느 한쪽이 NaN이면 false 반환. 따라서 NaN은 절대 NaN과 같지 않음.
  • Boolean: 피연산자가 둘 다 true이거나 둘 다 false일 때만 true 반환.
  • BigInt: 두 피연산자가 같은 값을 가질 때만 true 반환.
  • Symbol: 두 피연산자가 같은 symbol을 참조할 때만 true 반환.

피연산자 중 하나가 null 또는 undefined이면, 다른 쪽도 true를 반환하려면 null 또는 undefined여야 합니다. 그렇지 않으면 false를 반환합니다.

피연산자 중 하나가 객체이고 다른 하나가 원시 값이면, 객체를 원시 값으로 변환합니다.

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

  • 같은 타입이면 1단계를 사용해 비교합니다.
  • 피연산자 중 하나가 Symbol인데 다른 쪽이 아니면 false를 반환합니다.
  • 피연산자 중 하나가 Boolean인데 다른 쪽이 아니면, 불리언을 숫자로 변환합니다: true는 1로, false는 0으로 변환됩니다. 그런 다음 두 피연산자를 다시 느슨하게 비교합니다.
  • Number ↔ String: 문자열을 숫자로 변환합니다. 변환 실패는 NaN을 초래하며, 이는 동등성이 false임을 보장합니다.
  • Number ↔ BigInt: 수학적 값으로 비교합니다. 숫자가 ±Infinity 또는 NaN이면 false를 반환합니다.
  • String ↔ BigInt: BigInt() 생성자와 같은 알고리즘을 사용해 문자열을 BigInt로 변환합니다. 변환에 실패하면 false를 반환합니다.

느슨한 동등성은 대칭적입니다. 어떤 값 AB에 대해 A == B는 항상 B == A와 동일한 의미론을 가집니다(적용되는 변환 순서 제외).

이 연산자와 엄격 동등(===) 연산자의 가장 주목할 만한 차이는, 엄격 동등 연산자가 타입 변환을 시도하지 않는다는 것입니다. 대신 엄격 동등 연산자는 항상 서로 다른 타입의 피연산자를 다르다고 간주합니다. 엄격 동등 연산자는 본질적으로 단지 1단계만 수행하고 다른 모든 경우에는 false를 반환합니다.

위 알고리즘에는 "의도적 위반(willful violation)"이 있습니다: 피연산자 중 하나가 document.all이면 그것은 undefined인 것처럼 취급됩니다. 이는 document.all == nulltrue이지만, document.all === undefined || document.all === nullfalse임을 뜻합니다.

예제 (Examples)

타입 변환 없는 비교 (Comparison with no type conversion)

1 == 1; // true
"hello" == "hello"; // true

타입 변환이 있는 비교 (Comparison with type conversion)

"1" == 1; // true
1 == "1"; // true
0 == false; // true
0 == null; // false
0 == undefined; // false
0 == !!null; // true, look at Logical NOT operator
0 == !!undefined; // true, look at Logical NOT operator
null == undefined; // true

const number1 = new Number(3);
const number2 = new Number(3);
number1 == 3; // true
number1 == number2; // false

객체 비교 (Comparison of objects)

const object1 = {
  key: "value",
};

const object2 = {
  key: "value",
};

console.log(object1 == object2); // false
console.log(object1 == object1); // true

문자열과 String 객체 비교 (Comparing strings and String objects)

new String()으로 만든 문자열은 객체라는 점에 유의하세요. 이 중 하나를 문자열 리터럴과 비교하면 String 객체가 문자열 리터럴로 변환되고 내용이 비교됩니다. 그러나 두 피연산자가 모두 String 객체이면 객체로 비교되며, 비교가 성공하려면 같은 객체를 참조해야 합니다.

const string1 = "hello";
const string2 = String("hello");
const string3 = new String("hello");
const string4 = new String("hello");

console.log(string1 == string2); // true
console.log(string1 == string3); // true
console.log(string2 == string3); // true
console.log(string3 == string4); // false
console.log(string4 == string4); // true

Date와 문자열 비교 (Comparing Dates and strings)

const d = new Date("1995-12-17T03:24:00");
const s = d.toString(); // for example: "Sun Dec 17 1995 03:24:00 GMT-0800 (Pacific Standard Time)"
console.log(d == s); // true

배열과 문자열 비교 (Comparing arrays and strings)

const a = [1, 2, 3];
const b = "1,2,3";
a == b; // true, `a` converts to string

const c = [true, 0.5, "hey"];
const d = c.toString(); // "true,0.5,hey"
c == d; // true

명세 (Specifications)

ECMAScript® 2027 언어 명세 — sec-equality-operators

더 알아보기