loading
반응형

자바스크립트(javascript)

동등 연산자 (==), (===) 어떤 방식으로 비교를 하길래 혼란스럽게 하는가

 

 

순번 링크페이지 아래 제목을 클릭하면 해당 링크페이지로 이동 됩니다.
1 JS - 자바스크립트(javascript) 동등 연산자 ==, === 이상하다, 혼란스럽다 - (1)
2 JS - 자바스크립트(javascript) 동등 연산자 ==, === 이상하다, 혼란스럽다 - (2)
3 JS - 자바스크립트(javascript) 동등 연산자 ==, === 이상하다, 혼란스럽다 - (3)

 

 

▶ Loose(느슨한) Equals & Strict(엄격한) Equals

💻 느슨한 등호 == 와 엄격한 등호 === 차이점 

 

느슨한 등호 (==)는 두 피연산자에 같은지 에 대한 두 값을 비교하는 데 사용된다.

엄격한 등호(===)느슨한 등호(==)는 차이점이 있는데, 

 

  • 느슨한 등호(==)는 강제를 허용.
  • 엄격한 등호(===)는 강제를 허용하지 않는다.

 

두 개의 등호의 차이점은 강제를 허용한다와 허용하지 않는다의 차이점이 있다.

이 차이점은 유형이 일치하지 않는 경우를 말하며, 일치하지 않았을 경우 응답하는 방식이 차이이다.

 

 

지금 느슨한등호, 엄격한등호 얘기하면서 무슨 뚱딴지 같은 말을 하고 있는지 생각 할 수도 있는데,

차근차근 글을 읽어 내려가다보면 원초적인 이유에 대해 설명하고 있으니 꾸준히 읽어내려가면

이해하는데 도움이 될 것이다.

 

 

ECMAScript5 spec # 11.9.3 링크

 

 

ECMAScript5 spec # 11.9.3

 

 

위 링크를 들어가 보면 느슨한 동등 연산자(==)의 동작의 추상 평등 비교 알고리즘으로 정의된다고 한다.

여기에 나열된 것은 모든 유형의 조합과 각 조합에 대해 강제 변환이 발생하는 방법을 알고리즘이라 설명한다.

 

즉, 쉽게 말해 이 느슨한 동등 연산자(==)는 두 개의 피연산자를 비교를 할 때 유형 각각 피연산자에게

형 변환을 시도하여 두 개의 피 연산자가 같은지 아닌지 비교를 하는 것이다.

 

이 작업이 굉장히 복잡하다.

개발자들은 코딩할 때, 두 개의 피연산자가 같은지 아닌지만 알면 되는데,

 

그래서 느슨한 동등 연산자를 사용했지만 예상치 못한 결과가 나오는 것들이 있어서,

이 느슨한 동등 연산자를 사용하려면

 

자바스크립트는 피연산자에 대해 (==) 이와 같은 느슨한 동등 연산자를 사용할 경우 저 위와 같은

알고리즘 형태로 분석 파악해서 비교를 한다. 

 

그래서 내가 느슨한 동등 연산자를 꼭 사용한다 싶으면 저 위의 알고리즘이 어떤지 다 파악하고 느슨한 동등 연산자를 사용해야 한다.

 

우선 이 내용을 이해하기 전에 형 변환에 대해 어느 정도 지식이 있어야 이해하기 쉽다.

동등 연산자가 피연산자의 비교를 위해 강제적으로 형 변환을 시도해 두 개의 값이 같은지 아닌지를 판별하기 때문에(이 작업이 추상작업),

 

ECMAScript5 spec 11.9.3번의 내용은 이전 글 형 변환에 대한 글에서 다 정리한 내용이다.

형 변환에 대한 어느 정도 개념이 잡혀 있어야 이 동등 연산자를 이해하기 쉬울 것이다.

이 전 글에 형 변환에 대한 글을 확인하고 이 글을 읽는다면 큰 도움이 될 것이다.

 

아래 링크를 달아놓겠다.

형 변환에 대한 글 링크

1. 형 변환에 대하여 - (1)
2. 형 변환에 대하여 - (2)
3. 형 변환에 대하여 - (3)
4. 형 변환에 대하여 - (4)
5. 형 변환에 대하여 - (5)
6. 형 변환에 대하여 - (6)

 

 

 

자 이제 잡담은 뒤로하고 위 spec을 함 봐보자.

1. if Type(x) is the same as Type(y), then  - 유형 (x)이  유형(y)과 동일한 경우

비교되는 두 값이 동일한 유형인 경우 예상대로 간단하고 자연스럽게 값만 확인하면 된다고 한다.

 

var numA = 100;
var numB = 100;
var strA = 'JS';
var strB = 'JS';

if(numA == numB){
	console.log('ok');
}

if(strA == strB){
	console.log('ok');
}

 

 

numAnumB는 유형이 같은 숫자이고 이제 값만 비교하면 if문을 통과하여

console.log가 'ok'를 출력할 것이다. 마찬가지로 strAstrB도 같을 것이다.

 

이렇게 동일한 유형끼리 비교를 한다면 문제가 안된다.

11.9.3.1.a ~ 11.9.3.1.f의 내용은 이전 글 형 변환 내용에 전부 있는 내용이다.

 

그래서 간단하게 얘기하자면 각 타입마다 명시적 / 암묵적으로 형 변환을 시도하고,그 값으로 비교를 한다고 생각하면 된다.

 

 

 11.9.3.1.a ~ 11.9.3.1.f  이 범위의 몇 개 정도만 코드로 예제를 확인해 보겠다.

11.9.3.1 내용이 Type(x)와  Type(y)의 값이 같을 때 이니깐

 

1). ( a. If Type(x) is Undefined, return true.)

 

var aa;
var bb;

console.log(aa); // undefined
console.log(bb); // undefined

if(aa == bb){
  console.log('yes')
}

 

aabb변수는 값이 안 들어있는 초기화가 안 된 undefined이다.

그렇지만 둘이 느슨한 등호 연산자로 비교했을 때 true이다.

 

그래서 if문 console.log의 'yes'가 찍히는 것이다.

즉, 이 a의 내용은 둘 다 같은 타입, undefined 일 때 느슨한 등호(==) 비교 시 같다는 것.

 

 

2). ( b. If Type(x) is Null, return true.)

 

var aa = null;
var bb = null;

if(aa == bb){
	console.log('yes');
}

 

이 내용도 a와 똑같다.

두 개의 변수가 각각 null이라는 값을 가졌을 때,

느슨한 등호 연산자(==) 비교했을 때, true라서 if문 console.log의 'yes'가 찍힐 것이다.

 

이제 좀 다른 Number 타입을 확인해보자.

이 내용은 이전 글 형 변환에서도 정리했지만, NaN 값에 대해서 다르기 때문에 확인해보자.

 

 

3. (c. If Type(x) is Number, then) 

 

var aa = NaN;
var bb = NaN;

if(aa == bb){
	console.log('yes');
}

 

aabb 변수에 NaN이라는 값을 주고 if문 안에 console.log 가 출력되는지 확인해보자.

출력이 되는가?

 

안될 것이다.

NaN의 의미는 NaN은 타입이 숫자이지만 실패한 숫자라고 생각하면 된다.

약간 이해가 어렵다면 이전 글 Number 타입에 대한 글을(링크) 읽으면 이해가 쉽다.

 

암튼 저렇게 NaN

ECMAScript5 spec # 11.9.3.1.c의 내용 중 ⅰ,ⅱ 에 해당하는 내용이다. 

false를 반환하니 저 if문안에 console.log가 출력이 안된다.

 

 

 

 

반응형

 

 

💻 문자열과 숫자 (==), (===) 비교 

 

var numA = 100;
var numB = '100';

if(numA == numB){
	console.log('yes');
}

 

개발하면서 이러한 종류의 코드를 봤을 때 난감했을 것이다.

다른 프로그래밍을 하다가 넘어왔다면 이해가 안 갔을 건데... 참 혼란스럽게 그지없다.

 

이 if 문은 true이므로 console.log의 'yes'를 출력할 것이다.

애초에 숫자 100과 문자열 100인데 달라야 하는 게 맞지 않은가? 

 

자 처음에 얘기했던 

느슨한 등호(==)는 강제를 허용하고,

엄격한 등호(===)는 강제를 허용하지 않는다.

 

이 의미를 이 예제에서 얘기를 해보겠다.

numAnumB는 숫자는 같지만, 타입이 다르다.

 

그래서 이 느슨한 부등호(==)가 둘 중 하나 numA, numB를 강제 형 변환을 시도하여, 

비교를 해서 if문으로 들어와 console.log를 출력한 것이다.

 

즉, 이 느슨한 부등호(==)는 강제 형 변환을 시도한 것이다.

그래서 우리가 개발하면서 이상하다 이상하다.. 왜 자바스크립트의 부등호는 내가 가지고 있는 개념과

 

다를까?라는 생각을 하게 된 것이다.

자 여기서 그럼 궁금한 점이 있을 건데 느슨한 등호(==)가 저 numAnumB가 둘 중 하나가 강제로 

 

형 변환을 시도한다고 했는데 그럼 두 개의 변수 중 누가 문자열이 되고 누가 숫자가 되는가?

이것 또한 ECMAScript5 spec # 11.9.3.4 ~ 11.9.3.5 내용에서 친절이 알려준다.

 

 

4. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
(Type(x)가 숫자이고 Type(y) 문자열이면 느슨한 등호(==) 비교 시 Type(y)를 숫자로 형 변환한다.)

5. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
(Type(x)가 문자열이고 Type(y)가 숫자이면 느슨한 등호(==) 비교 시 Type(x)를 숫자로 형 변환한다.)

 

 

그럼 엄격한 등호를 봐보자.

 

var numA = 100;
var numB = '100';

if(numA === numB){
	console.log('yes');
}

 

 

이 if문을 통과를 해서 'yes'를 출력할까?

답은 NO! 이렇게 엄격한 부등호를 사용하면 강제 형 변환이 일어나지 않는다.

 

그래서 숫자 100과 문자열 '100' 은 다르기 때문에 저 if문을 통과하지 못한다.

 

 

💻 문자열과 Boolean (==), (===) 비교 

 

var stringNumber = '100';
var bool = true;

if(stringNumber == bool){
console.log('yes');
}

 

어떨까? 'yes'를 출력을 못한다.

대부분 사람들은 아마 저거는 당연한 거 아닌가?라고 생각할 듯싶다.

 

같은 타입도 아닌 거와 숫자와 true 라니... 저건 느슨한 등호로 해도 true가 안될 거 같은데?

라는 생각을 말이다.

 

하지만 형 변환에 대해서 어느 정도 지식이 있는 사람이라면 엇? 할 것이다.

이전 글 형 변환에 대해서 얘기했지만 문자열을 Boolean으로 형 변환을 하면  true 값이 된다.

 

즉, ToBoolean 규칙에 의해 변수 stringNumber가 true를 반환하는데,

그렇다면 저 위에 if문의 구문은 통과가 되어 'yes'가 출력되어야 하는 게 아닌가? 

 

하지만 이것도  ECMAScript5 spec # 11.9.3.6 ~ 11.9.3.7  이 내용에서 친절히 알려준다.

 

6. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
( Type(x)가 Boolean 이면 ToNumber(x) == y 비교 결과를 반환한다. )

7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
( Type(y)가 Boolean 이면 x == ToNumber(y) 비교 결과를 반환한다. )

 

이렇듯 stringNumber 변수가 boolean 으로 강제 변환되는게

아니라 bool 변수가 숫자로 강제 형 변환이 되는 것이다.

 

bool 변수는 강제로 ToNumber 규칙에 의해 숫자로 형 변한 이 되어서 1이 된고,

 

if('100' == 1){
	console.log('yes');
}

 

이렇게 된 다음에

stringNumber 변수는 강제로 숫자 형 변환이 되어서 숫자 100 이 되고,

 

 

그러므로 

 

// 결과는

if(100 == 1){
	console.log('yes');
}

 

이런 식이 되는 것이라 if문을 통과를 못하는 것이다.

 

다음 내용은 null 과 undefine의 비교시 혼란스러운 부분을 정리해보자.

반응형

+ Recent posts