유튜브 [썬한코딩]입사에 필요한 JS 기술 영상 내용을 보고 학습한 내용을 정리합니다.
1번 문제
if(2 == ___ ) 중에 밑줄에 값이 들어올때 true가 아닌 경우?
- Number(2)
- Number(2).valueOf()
- Number(2).toString()
- 2.valueOf()
- 2 .toString()
답은 몇번일까요?
이 문제에서 포인트는 3가지입니다.
==
, ===
의 차이===
일치[1,2] === [1,2]
는 false 이다.==
동치(동등비교)==
동치는 ===
일치 비교를 포함한다. 즉 ===
이 참이면 ==
도 참이다.
==
는 느슨한 동등 비교를 한다. 즉 타입이 같지 않을 경우, 강제 형변환(type coercion) 을 수행하여 비교한다.
자세한 형변환 규칙은 ECMAScript에서 지정한 동등 비교 연산 알고리즘을 참고하자. The Abstract Equality Comparison Algorithm
다음 몇가지 경우를 살펴봅니다.
null == undefined
0 == '0'
'0'
을 숫자로 형변환하여 0 == 0
true == '1'
true
를 숫자로 형변환하면 1
, '1'
을 숫자로 형변환 1
0 != 'a'
'a'
를 숫자로 형변환하면 NaN
NaN은 어느 값과도 일치하지 않는 특성이 있다.
NaN === NaN; // false
NaN
판별하기 MDN - NaN
isNaN()
: 현재 값이 NaN 이거나, 숫자로 변환했을 때 NaN 일 경우 true 반환Number.isNaN()
: 현재 값이 NaN 일 경우, true 반환- NaN 만이 자기자신과 비교했을때 같지 않다는 특성 이용
function valueIsNaN(v) { return v !== v; }
위에서 다른 기본형끼리 동등비교 시에는 형변환 하는 것을 보았다.
참조형끼리 비교할 경우에는 ===
와 마찬가지로 참조값을 비교한다.
그렇다면 참조형과 기본형을 비교하는 경우에는 어떨까?
[2,3] == '2,3'
valueOf
를 수행한다. valueOf
결과가 기본형이 아니면, toString()
을 수행한다.1.123
이 있을 때 인터프리터는 숫자값 1.123 인지, 1의 프로퍼티 123을 말하는 것인지 구분하기 힘들기 때문에 숫자 다음 . 이 왔을 때는 무조건 소수라고 해석한다.
따라서 1.toString() 을 하게 되면 SyntaxError가 발생한다.
SyntaxError: Unexpected identifier after numeric literal (Edge)
SyntaxError: identifier starts immediately after numeric literal (Firefox)
SyntaxError: Unexpected number (Chrome)
대신 1 .toString()
처럼 1 뒤에 띄어쓰기를 하고 . 을 사용하게 되면, 1뒤에 소수부가 없다고 판단하여 원하는대로 실행할 수 있다.
마찬가지로 1.2.toString()
처럼 소수부가 있는 경우 사용하게 되면 뒤에 또 .이 올 수 없음을 알기 때문에 바로 toString을 사용할 수 있다.
만약 프로퍼티가 없는 경우에는 TypeError가 발생한다.
예를 들어 1 .aa()
를 실행하면 Uncaught TypeError: 1.aa is not a function
에러가 발생한다.
1번 문제의 답은 4번이었습니다.
SyntaxError 에러가 발생하겠죠?
숫자 뒤에 .
을 사용할 때 띄어쓰기 해야함을 어디선가 본 적이 있는데 이번기회에 한번 더 정리할 수 있었습니다.
number, string, array, boolean 의 toString 메서드는 다음과 같이 출력됩니다.
2 .toString() // 2
[1,2].toString() // 1,2
["aa","bb"].toString() // aa, bb
true.toString() // true
타입체크할 때 사용한 toString은 Object의 메서드였음도 다시한번 정리해봅니다.
Object.prototype.toString
메서드를 이용한 타입체크
- 객체를 나타내는 문자열을 반환
Object.prototype.toString.call(''); // [object String] Object.prototype.toString.call(new String()); // [object String] Object.prototype.toString.call(1); // [object Number] Object.prototype.toString.call(new Number()); // [object Number] Object.prototype.toString.call(NaN); // [object Number] Object.prototype.toString.call(Infinity); // [object Number] Object.prototype.toString.call(true); // [object Boolean] Object.prototype.toString.call(undefined); // [object Undefined] Object.prototype.toString.call(); // [object Undefined] Object.prototype.toString.call(null); // [object Null] Object.prototype.toString.call([]); // [object Array] Object.prototype.toString.call({}); // [object Object] Object.prototype.toString.call(new Date()); // [object Date] Object.prototype.toString.call(Math); // [object Math] Object.prototype.toString.call(/test/i); // [object RegExp]