동등성 비교
- ES5 이전 JS 에서는 보통 동등성 비교에 2개의 부호만 사용했다.
==
와===
이다.
- ES6 에서 Object.is() 가 나왔다.
- 이 메서드는 자바스크립트 언어 스펙을 정하는 위원회의 앞으로의 방향을 나타내기 때문에 중요하다.
동등성 알고리즘 정리
그렇다면 동등성 알고리즘은 어떤 것들이 존재할까?
- IsLooselyEqual:
==
- IsStrictlyEqual:
===
- SameValue:
Object.is()
,Object.prototype.defineProperty()
에서의 빌트인 동등성 비교 연산 - SameValueZero:
Array.prototype.includes()
혹은Map
에서의 빌트인 동등성 비교 연산
프리미티브에 대한 처리 때문에 이렇게 나뉘게 되었다.
==
의 특징
- Equality operator 라고 불린다.
- 타입 변환이 일어난다.
- IEEE 754 에 따라
NaN
,-0
,+0
을 다룬다.- IEEE 754 에 따라
NaN != NaN
이고,-0 == +0
이다.
- IEEE 754 에 따라
- 타입 변환의 모든 규칙을 외우고 있다면, 활용해도 좋다.
- 그러나 보통은 실수만 유발할 뿐이므로 전부 외워서 활용하기보다 그냥 쓰지 않는 편이다.
예제 코드
console.log(1 == "1"); // true
console.log(1 == "one"); // false
console.log(1 == "x1"); // false
console.log(1 == "0x1"); // true
console.log(0 == false); // true
console.log(NaN == NaN); // false
console.log(-0 == +0); // true
console.log(undefined == null); // true
console.log(null == undefined); // true
console.log(null == false); // false
console.log(undefined == false); // false
console.log(null == null); // true
console.log(undefined == undefined); // true
1 == "1"
이true
인 이유String
타입과Number
타입이 비교되는 경우,String
타입을Number
타입으로 변환시켜서 비교한다.
1 == "one"
이false
인 이유Number
로 변환될 수 없는String
은NaN
으로 변환되어 거짓이 나온다.
0
와false
는Boolean
의 형변환과 관련이 있다.Boolean
의 경우true
면1
,false
면0
으로 변환된다.
자세한 규칙은 공식문서 에 적혀져 있다.
===
의 특징
- Strict equality operator 라고 불린다.
- 타입 변환이 일어나지 않는다.
- 이에 따라
==
에서 알아둬야 할 복잡한 규칙이 모두 사라진다. 생각할 것이 많이 줄어든다.
- 이에 따라
- 타입이 다르면 무조건
false
를 반환한다. - 여전히
NaN !== NaN
이다.
예제 코드
console.log(1 === "1"); // false
console.log(1 === "one"); // false
console.log(1 === "x1"); // false
console.log(1 === "0x1"); // false
console.log(0 === false); // false
console.log(NaN === NaN); // false
console.log(-0 === +0); // true
console.log(undefined === null); // false
console.log(null === undefined); // false
console.log(null === false); // false
console.log(undefined === false); // false
console.log(null === null); // true
console.log(undefined === undefined); // true
적용된 빌트인
- 인덱스 찾는 메서드들에 적용되어 있다.
- switch case 에 적용되어 있다.
SameValue
동등성 알고리즘 (Object.is()
) 특징
- 기본적으로
===
와 결과가 거의 흡사하지만 몇가지가 다르다. NaN
과NaN
을 비교하면true
를 반환한다.-0
과+0
을 구분한다.
예제 코드
console.log(Object.is(1, "1")); // false
console.log(Object.is(1, "one")); // false
console.log(Object.is(1, "x1")); // false
console.log(Object.is(1, "0x1")); // false
console.log(Object.is(0, false)); // false
console.log(Object.is(NaN, NaN)); // true
console.log(Object.is(-0, +0)); // false
console.log(Object.is(undefined, null)); // false
console.log(Object.is(null, undefined)); // false
console.log(Object.is(null, false)); // false
console.log(Object.is(undefined, false)); // false
console.log(Object.is(null, null)); // true
console.log(Object.is(undefined, undefined)); // true
적용된 빌트인
Object.defineProperty()
에서value
를 변경할 때 이 동등성 알고리즘을 이용해 변경됐으면 실제로 값을 변경하고, 아니라면 아무런 동작도 하지 않는다.
// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO", {
value: -0,
writable: false,
configurable: false,
enumerable: false,
});
function attemptMutation(v) {
Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
attemptMutation(-0); // writable 하지 않고, configurable 하지 않지만, SameValue 알고리즘에 의해 같은 값으로 판독돼서 에러가 발생하지 않음
attemptMutation(0); // SameValue 알고리즘에 의하면 다른 값이기 때문에 에러가 발생함
SameValueZero
동등성 알고리즘 특징
- 이름처럼
SameValue
알고리즘에서+0
과-0
을 동일하게 취급하도록 바뀐 알고리즘 정도로 보면 된다. - 이 알고리즘은 직접적으로 비교할 수 있는 연산자나 메서드가 없다.
- 아래와 같은 가상의 함수가 있다고 생각하면 된다.
function sameValueZero(x, y) {
if (typeof x === "number" && typeof y === "number") {
// x and y are equal (may be -0 and 0) or they are both NaN
return x === y || (x !== x && y !== y);
}
return x === y;
}
적용된 빌트인
몇가지 예제 코드
const arr = [+0, 1, 2, 3];
console.log(arr.includes(-0)); // true
+0
과-0
에 대해true
를 반환하기 때문에 가능하다.
const arr = [0, 1, NaN, 2, 3];
console.log(arr.includes(NaN)); // true
SameValue
에서0
처리만 바뀌었다고 생각하면, 당연히NaN
동등성 비교도 가능하다.
반응형
'자바스크립트 > 모던 자바스크립트' 카테고리의 다른 글
모던 자바스크립트, 셋 혹은 세트 (Set) (0) | 2023.03.23 |
---|---|
모던 자바스크립트, 맵 (Map) (0) | 2023.03.23 |
모던 자바스크립트, Reflect (리플렉트) 객체란? (0) | 2023.03.20 |
모던 자바스크립트, TypedArray (타입이 있는 배열) (0) | 2023.03.19 |
모던 자바스크립트, ES2019 의 stable 내장 정렬 (Array.prototype.sort) (0) | 2023.03.15 |