타입 시스템
- JS는 굉장히 느슨한 동적 타입의 언어임
- 프로그램 처리 과정이 런타임 시점에서 자동으로 파악되기 떄문에 그럴 때 보는 타입에서만 보임
- 그래서 타입을 할 때 굉장히 조심해서 다뤄야함
- 타입은 보통 원시값(Primitive)과 객체타입(Reference) 2가지로 나뉘어짐
- 참고자료
원시값
typeof undefined
typeof true
typeof 'string'
typeof 123
typeof 9007199254740992n;
typeof Symbol()
typeof null
- 위의 타입을 대표적인 원시값 타입이라고 볼 수 있음
- 원시 타입은 또한 불변하다는 특징을 가지고 있음
- 아무리 문자열을
toUpperCase
로 주더라도 값 자체가 바뀌지 않음(boolean도 마찬가지), 아래와 같이 재할당을 해야함(불변한 값이므로)
let test = 'string';
test = test.toUpperCase();
console.log(test);
const bool = false;
bool = !bool;
console.log(bool);
참조 타입
- 객체 타입, 참조 타입, Reference 타입이라고 부름
- 객체, 배열, 함수를 참조 타입이라고 할 수 있음
const object = {};
const array = [];
function func() {}
- 실제 메모리에 존재하는 참조 타입일 경우
instanceof
함수로 확인해볼 수 있음
- 객체의 경우 아래와 같이 객체 안에 속성이 들어가고 (
,
연산자를 통해서 다양한 값을 넣을 수 있음(함수도 넣을 수 있고 다른 객체 다양하게 들어갈 수 있음)
- 그래서 이를 데이터 컬렉션이라고도 하는 경우가 있음
- array 같은 경우도 함수도, 배열도 다양하게 넣을 수 있음
- 이러한 것의 특징은 불변하지 않고 가변적이면서도 그 안의 값은 예시처럼 메모리 주소가 가지고 있음
- 그래서 Object 타입의 경우 일종의 메모리를 가지고 주소를 가지고 있는 것(어딘가에 값이 저장되고)
const object = {
name: 'jang',
age: 11,
arr: [],
func: function() {},
child: {}
};
const array = [[], 11, 'jang', function() {}];
- 객체의 경우, 아래와 같은 성격으로 가변적이라고 볼 수 있음
const obj = {
str: 'string'
}
obj.str.toUpperCase();
obj.num = 123
obj.bool = true
- 배열의 경우도 아래와 같이 볼 수 있음(마찬가지로 불변적이면서 가변적이라는 것)
const arr = [1,2,3];
console.log(arr[0]);
arr[3] = 1000
undefined & null
- 변수는 선언 & 할당 & 선언과 동시에 할당되는 케이스로 구분할 수 있음
- 이 때 undefined의 경우 할당되지 않은 경우임(정의가 되지 않은 것), 즉, 변수를 선언만 하고 할당 & 정의를 하지 않은 것
- null의 경우 직접 null을 지정한 것임, 그래서 이 차이가 undefined와 null의 차이임
let variable;
const initValue = null
variable
initValue
- 비어있는 값을 처리하기 위해서 임의로 null, undefined를 넣어서 쓰는 경우도 있음
- 이 때 undefined, null 모두
!
를 쓰면 true가 되고, !!
로 하면 false가 됨(둘 다 같은 값으로 여겨짐, 느슨한 비교일 경우)
- 하지만 이를 명시적으로
Number(undefined)
로 하면 NaN
으로 되고 Number(null)
로 하면 0
이 됨
- 이는 느슨한 비교와 명시적으로 한 경우, 다 다름
- 그래서 어느정도 규칙을 정해야 규칙과 목적성 있게 해당 값을 다룰 수 있음(둘 중 하나만 명확하게 기준을 잡고 쓰기)
래퍼 객체
- 원시값의 래퍼 객체라고 아래와 같이 존재함(파스칼 케이스로 정의해서 씀, 생성자 함수로 만듬)
- 이렇게 생성자 함수 래퍼 객체로 만든 것은 타입이 다름(object임), 그러한 객체로 인스턴스가 생성됐다고 볼 수 있음
const bool = false;
const num = 123;
const str = 'string';
const bool2 = new Boolean(false);
const num2 = new Number(123);
const str2 = new String('string');
console.log('string' instanceof String);
- 이를 원시값으로 되돌리고자 한다면
valueOf()
를 쓸 수 있음
- 래퍼 객체를 안 쓰는게 나을 수 있음
- string을 원시값으로 쓸 때, 래퍼객체로 만들고 가비지 콜렉터로 사라짐, 다른 객체로써 불러올 때도 마찬가지
- 래퍼객체 안에 아주 많은 메소드들이 있는데 그래도 그냥 리터럴로 편하게 써도 무방함
타입 변환
!!
로 Boolean으로 형변환을 하거나 명시적으로 Number(값)
, String(값)
, Boolean(값)
, Array.from()
등 있음
- 아래와 같이 암시적인 형변환도 있음.
const result1 = 1 + '입니다'
const result2 = '11' + 11
const result3 = '2' * '2'
const result4 = '5' * 3
const result5 = ['111'] + '111'
- 위와 같은 경우 명시적으로 형변환해서 하는게 좋음, js의 경우 형 변환이 문자열로 되는 경우도 꽤 있음(불명확함)
const result1 = String(1) + '입니다'
const result2 = Number('11') + 11
const result3 = Number('2') * Number('2')
const result4 = Number('5') * 3
const result5 = Number(String(['111'])) + 111
- 그래서 명시적으로 형변환을 하고 확실히 해야함. 사용자의 입력을 받고 처리하기 때문에 필히 명시적으로 해야함