티스토리 뷰
🔖TAG 💡eqeq, 💡instanceof, 💡isNaN, 💡null, 💡Primitive, 💡reference, 💡typeof, 💡undefined, 💡타입검사, 💡형변환 📕

출처😌
자료🙄
Git: pocojang/clean-code-js (github.com)
목차
1. 과정 소개
2. 변수 다루기
3. 타입 다루기 🚩
3-1. 타입 검사
3-2. undefined & null
3-3. eqeq 줄이기
3-4. 형변환 주의하기
3-5. isNaN
4. 경계 다루기
5. 분기 다루기
6. 배열 다루기
7. 객체 다루기
8. 함수 다루기
3. 타입 다루기
3-1. 타입 검사
typeof 는 문자열로 반환하는 연산자 입니다.
const str = '문자열'
const num = 123
const bool = true
const nul = null
const und = undefined
const sym = Symbol('sym')
console.log(typeof str); // string
console.log(typeof num); // number
console.log(typeof bool); // boolean
console.log(typeof nul); // object
console.log(typeof und); // undefined
console.log(typeof sym); // symbol
console.log(typeof (sym)); //symbol <- typeof를 함수처럼 사용해도 됩니다.
타입을 검사할 때 typeof 로 모든걸 커버할 수 있지 않을까? 라는 생각이 드는데요,
그렇지는 않습니다.
타입은 2가지로 나눌 수 있습니다.
PRIMITIVE(원시값) vs REFERENCE(객체)
원시값은 불변하다는 특징을 가지고 있습니다.
REFERENCE는 Object로 볼 수 있는데 종류가 다양합니다. (Array, function, Date etc...)
function myFunction() {}
typeof myFunction // 'function'
class MyClass {} // Class는 생성자 함수처럼 이루어져 있는 객체를 만들어내는 표본입니다.
typeof MyClass // 'function'
class가 function으로 나오는 걸 보니 typeof가 많은 걸 인용할 수 없다는 것을 알 수 있습니다.
Wrapper 객체를 사용할 때는 Object로 나옵니다.
const str = new String('문자열')
typeof str //'object'
이처럼 PRIMITIVE 자료형은 원하는 대로 잘 나오는걸 볼 수 있습니다.
그러나 REFERENCE 값은 typeof로 감별해내기가 어려울 수 있습니다.
결론은 typeof가 타입을 알아볼 수 있는 만능이 아니라는걸 알아야 합니다.
치명적인 오류 중에 하나는 null 타입을 볼 때가 있습니다.
typeof null // 'object'
PRIMITIVE vs REFERENCE 를 감별해 내기 어려운 경우가 또 있습니다.
JS는 동적으로 변하는 언어이기 때문에 타입 까지 동적입니다.
그 중 하나가 instanceof 연산자가 있습니다.
instanceof 연산자는 객체의 프로토타입 체인을 검사하는 기능을 가지고 있습니다.
function Person(name, age) {
this.name = name
this.age = age
}
const person1 = new Person('BOB', 10)
person1 instanceof Person // true
const person2 = {
name: 'BOB',
age: 10
}
person2 instanceof Person // false
const arr = []
const func = function() {}
const date = new Date()
arr instanceof Array // true
func instanceof Function // true
date instanceof Date // true
arr instanceof Object // true
func instanceof Object // true
date instanceof Object // true
// 결국 REFERENCE 타입의 최상위 타입은 Object 입니다.
// 프로토타입 체인을 타다보면 Array -> Object, Function -> Object, Data -> Object 로 가게됩니다.
// 그래서 instanceof로도 타입검사가 어려움이 있습니다.
타입을 검사하는 3번째 방법은 아래와 같습니다.
Object.prototype.toString.call('') // [object String]'
Wraper 객체까지 감지해 낼 수 있습니다.
Object // ƒ Object() { [native code] }
Object.prototype
// constructor: ƒ Object()
// hasOwnProperty: ƒ hasOwnProperty()
// isPrototypeOf: ƒ isPrototypeOf()
// propertyIsEnumerable: ƒ propertyIsEnumerable()
// toLocaleString: ƒ toLocaleString()
// toString: ƒ toString()
// valueOf: ƒ valueOf()
// __defineGetter__: ƒ __defineGetter__()
// __defineSetter__: ƒ __defineSetter__()
// __lookupGetter__: ƒ __lookupGetter__()
// __lookupSetter__: ƒ __lookupSetter__()
// __proto__: (...)
// get __proto__: ƒ __proto__()
// set __proto__: ƒ __proto__()
Object.prototype.toString // ƒ toString() { [native code] }
Object.prototype.toString.call() // [object Undefined]'
//Wraper 객체까지 감지해 낼 수 있습니다.
Object.prototype.toString.call('') // [object String]'
Object.prototype.toString.call(new String('')) //'[object String]'
Object.prototype.toString.call( [] ) //'[object Array]'
Object.prototype.toString.call( {} ) //'[object Object]'
Object.prototype.toString.call( function(){} ) //'[object Function]'
Object.prototype.toString.call( null) //'[object Null]'
Object.prototype.toString.call( new Date() ) //'[object Date]'
요약
1. JS언어는 동적인 타입을 가지는 언어입니다. 그래서 타입검사가 어렵습니다.
하나하나 잘 찾아서 타입을 알아봐야 정확하게 알 수 있습니다. (스택오버플로우 참고)
그러나, 일일이 타입을 외우지 말아야 합니다(낭비)!
2. Primitive vs Reference 타입을 잘 구분해야 합니다.
typeof 가 타입을 구분짓는 무적은 아닙니다. 타입 구분에 instanceof도 쓰입니다.
3-2. undefined & null
meme1

!null // true
!!null // false
null === false // false
!null === true // true
// null은 수학연산에서 0으로 취급됩니다.
null + 123 // 123
// undefined는 아무것도 선언하지 않은 기본값이라고 생각하면 됩니다.
// 아래는 선언했지만 값은 정의되지 않았습니다.
let empty;
empty // undefined
typeof empty // 'undefined'
// undefined는 수학연산에서 값으로 쓰이지 않습니다.
undefined + 123 // NaN
!undefined // true
undefined == null // true
undefined === null // false
!undefined === !null // true
// 결국 undefined와 null을 사용할 때 자신만의 컨벤션을 만들어 가는게 중요합니다.
요약
1. undefined, null은 값이 없거나 정의되지 않은 것입니다.
'값이 없다'는건 명시적인 표현을 말합니다.
2. null은 숫자적으로 표현할 때 0에 가깝다고 볼 수 있고, typeof null은 'Object' (대표적 오류)가 나옵니다.
undefined는 숫자적으로 NaN이고, typeof undefined는 'undefined'가 나옵니다.
3. undefined와 null을 사용할 때는 조심성을 가지고 써야합니다.
3-3. eqeq 줄이기
eqeq는 JS에서 동등 연산자를 의미합니다.
JavaScript 동등성 테이블 게임 (eqeq.js.org)
JavaScript Equality Table Game
Find out how well you know (or don't know) the JavaScript == operator rules
eqeq.js.org
동등연산자 '=='를 쓰면 형변환(type casing)이 일어납니다.
'1' == 1 // true
1 == true // true
// 엄격 동등 연산자
'1' === 1 // false
만약 어떤 값이 있는데
숫자 0 과 같은지 확인 할 때는, 직접 형변환을 해서 비교하길 추천합니다.
내가 동등 연산자를 잘 활용할 줄 안다고해서 자주 사용하면 절대 좋은것이 아닙니다.
오히려 동료들에게 혼란만 줄 뿐입니다.
그러니 동등 연산자('==')의 사용을 지양하시고 엄격 동등 연산자('===')를 사용하시면 좋겠습니다.
const ticketNum = {
value: 0,
}
ticketNum.value == 0 // true
Number(ticketNum.value) === 0 // true
참고 : eqeqeq - ESLint - Pluggable JavaScript Linter
3-4. 형변환 주의하기
암묵적인 형변환 VS 명시적인 형변환
① 암묵적인 형변환
동등 연산자('==')는 형 변환을 일으켜 느슨한 검사를 하는 연산자 입니다.
이렇게 형 변환을 자동으로 시켜주는 것을 '암묵적인 형변환'이라고 합니다.
따라서 아래의 검사가 다 유효합니다.
'1' == 1 // true
1 == true // true
0 == false // true
'암묵적인 형변환'에 대해서 조금 더 보겠습니다.
11 + ' 문자와 결합' // '11 문자와 결합'
!!'문자열' // true
!!'' // false
② 명시적인 형변환
사용자가 의도적으로 형변환을 시켜주는 것을 말합니다.
형변환을 할 때는 명시적으로 하는게 바람직합니다.
String(11 + ' 문자와 결합') // '11 문자와 결합'
Boolean('문자열') // true
Boolean('') // false
Number('11') // 11
parseInt('9.9999', 10) // 9
parseInt 같은 경우에 많은 분들이 헤깔릴 수 있습니다.
두 번째 인자는 꼭 넣어주는게 좋습니다. 두 번째 인자가 없을 땐 기본적으로 10진수로 계산 되지 않습니다.
예를 들어, 0x로 시작하면 16진법으로 처리합니다.
parseInt('0x100') // 256
참고: JS / 함수 / parseFloat(), parseInt() – 문자열을 수로 바꾸는 함수
JavaScript / 함수 / parseFloat(), parseInt() - 문자열을 수로 바꾸는 함수
parseFloat() parseFloat()는 문자열을 실수로 바꾸는 함수입니다. 문법 parseFloat( string ) 수로 시작할 때 그 수를 실수로 바꿉니다. 띄어 쓰기로 여러 개의 수가 있으면 첫번째 수만 바꿉니다. 공백으로
www.codingfactory.net
요약
명시적인 형변환: 사용자가 형변환 할 때
암묵적인 형변환 : JS가 평가해서 형변환 할 때
📌사람이 명시적으로 형변환을 시켜서 예측가능한 코드를 작성하는 것이 좋습니다.
3-5. isNaN
IEEE 754 - 위키백과, 우리 모두의 백과사전 (wikipedia.org)
사람이 생각하는 수는 10진수이고
컴퓨터가 생각하는 수는 2진수 입니다.
이러한 숫자의 인식차이 때문에 간극이 생기는데, 대표적인 예시가 소수점을 나타낼 때 입니다.
컴퓨터는 이 부동소수점을 나타낼때 IEEE 754 표준을 이용합니다.
Number.MAX_SAFE_INTEGER // 9007199254740991
Number.isInteger // ƒ isInteger() { [native code] }
isNaN으로 해당 요소가 숫자인지 판단하는것엔 문제가 많습니다.
// is Not A Number => 숫자가 아니다
isNaN(123) // false -> 숫자가 숫자가 아니다 (숫자가 맞다) <- 혼동
그래서 해당 요소가 숫자가 맞는지 판단할 때는, Number.isNaN(요소)로 검사하면 좋습니다.
// ES2015 이전
isNaN(123 + '테스트') // true
// ES2015+
Number.isNaN(123 + '테스트') // false
isNaN // 느슨한 검사
Number.isNaN // 엄격한 검사
'WEB > JavaScript' 카테고리의 다른 글
| [클린코드 For JS] 5. 분기 (0) | 2022.06.28 |
|---|---|
| [클린코드 For JS] 4. 경계 (0) | 2022.06.27 |
| [클린코드 For JS] 1. 소개 & 2. 변수 (0) | 2022.06.27 |
| 타자게임 - 데이터상태처리 (setInterval) & API 연동 (0) | 2022.06.16 |
| 타자게임 이벤트 처리 (basic) (0) | 2022.06.15 |