on
[Javascript]Data type
자바스크립트가 왜이럴까? 2번째 관문을 위한 시작 점
데이터 타입
자바스크립트의 값(데이터)의 타입은 ES6기준 총 7개가 있다. 많은 개발자들이 자바스크립트를 혐오하는 이유들 중에 동적 타이핑, 비교 연산, 타입 변환을 이해하려면 데이터 타입을 확실히 이해해야 한다.
또한 개발자 면접 단골 문제인 깊은 복사, 얕은 복사, 참조 등을 대답하기 위해선 데이터 타입의 공부가 베이스가 되어야 한다.
1. 원시 타입(primitive type / value type)
정수, 실수, 문자, 논리 리터럴 등의 실제 데이터 값을 저장하는 타입(숫자, 문자열, 불리언, undefined, null, symbol)
2. 객체 타입( object type / reference type)
객체(Object)의 주소를 참조하는 타입으로 메모리 주소 값을 통해 값을 참조하는 타입(함수, 배열, 객체)
자바스크립트에서 함수와 배열은 객체로 만들어져 있다. 따라서 함수, 배열, 객체를 각각 서로 다른 타입으로 이야기 하지 않고 객체 타입 하나로 나타낸다.
원시 타입의 종류
1. Number
자바스크립트의 경우 정수와 실수를 구분하지 않고 모든 숫자값을 배정밀도 64비트 부동소수점 형식을 따른다. 즉, 모든 수를 실수로 표현한다. 정수, 실수, 2진수, 8진수, 16진구 리터럴 모두 배정밀도 65비트 부동소수점 형식의 2진수로 저장하고, 참조하여 해석할 때는 모두 10진수로 해석한다.
let a = 0b01000001; //2진수
let b = 0o101; // 8진수
let c = 0x41; // 16진수
console.log(a, b, c); // 65, 65, 65
console.log(a === b); // true
console.log(b === c); // true
자바스크립트에서 정수로 표현되는 수도 사실 정수가 아니라 실수일 수 있다. 따라서 정수로 표시되는 수끼리 나누더라도 실수가 나올 수 있다. ( 소수점 계산은 더 조심하자😂😂😂 )
console.log(1 === 1.0); // true
let a = 0.1;
let b = 0.2;
console.log(a + b); // 0.30000000000000004
console.log(a + b === 0.3); //false
let value = 27500;
let tax = 1.1;
let cost = value * tax; // 30250.000000000004
숫자타입은 아래 3가지 특별한 값도 계산할 수 있다.
console.log(100 / 0); //Infinity, 양의 무한대
console.log(100 / -0); //-Infinity, 음의 무한대
console.log(1 * "name"); // NaN, 연산 불가(Not a number)
2. String
텍스트 데이터를 나타내는 데 사용한다. 문자열은 0개 이상의 유니코드 문자의 집합이다.
문자열은 ‘’, “”. ``(이하 문자열 방식)으로 텍스트를 감싸 표현한다.
let string0 = "작은 따옴표";
let string1 = "큰 따옴표";
let string2 = `백틱`;
만약에 문자열 방식 2중 이상으로 겹쳐져 있다면, 안의 방식은 문자열로 인식된다.
또한 문자열을 문자열 방식으로 감싸지 않으면 문자열이 아니라 토큰으로 인식된다.
당연히 문자열 방식으로 감싸지 않으면 공백 문자도 포함할 수 없고, 여러개의 토큰으로 인식한다.
템플릿 리터럴(Template literal)
ES6부터 제공하는 백틱 문자열 방식의 새로운 문자열 표기법이며, 여러 기능을 추가적으로 가능하게 한다.
1) 멀티라인 문자열
기존 큰따옴표나 작은 따옴표는 엔터로 개행(줄바꿈)할 수 없고, /n과 같은 이스케이프 시퀀스를 사용해야 한다. 하지만 템플릿 리터럴에서는 줄바꿈을 개행으로 인식한다.
let es5 = "이것은
ES5 문자의 일반적인
예시 입니다."
let es6 = `이것은
ES6 백틱을 사용한
템플릿 리터럴 예시입니다.`;
console.log(es5); // "이것은 ES5 문자의 일반적인 예시입니다."
console.log(es6); // `이것은
// ES6 백틱을 사용한
// 템플릿 리터럴 예시입니다.`;
2) 표현식 삽입(expression interpolation)
여러개의 문자열을 합하거나, 계산된 값을 문자열에 합해서 표현하는 것을 쉽게 할수 있도록 해준다. 합하려는 문자열이나 합수의 실행 값 등을 ${}로 감싸주기만 하면 된다.
const getUserName = (id) => {
let userName;
...user의 이름을 찾는 로직
return userName;
}
let userId = 3341;
let introduce = `안녕하세요, 제 이름은 ${getUserName(userId)}입니다.`
console.log(introduce) // `안녕하세요, 제 이름은 웨인입니다`
3) 태그드 탬플릿(tagged template)
템플릿 리터럴로 표현된 문자열을 분해할 수 있는 기능이다. tagged template로 이용할 함수에 템플릿 리터럴 문자열을 붙여서 실행한다.
let food1 = "피자";
let food2 = "치킨";
let food3 = "떡볶이;";
const foodMsg = (strings, ...values) => {
console.log(strings); // [ '제가 오늘 먹은 음식은 ','과', '그리고 ', '입니다.' ]
console.log(values); // [ '피자', '치킨','떡볶이' ]
};
foodMsg`제가 오늘 먹은 음식은 ${food1}과${food2} 그리고 ${food3}입니다.`;
strings에 리터럴로 분해된 문자열이 담겨있고,values에 food1~3이 담겨있는 것을 확인할 수 있다.
str의 length는 rest의 length보다 항상 1 크다. str의 마지막에 값이 없더라도 빈 문자열이 들어가기 때문이다.
tagged template는 직접적으로 사용하는 일이 없을 것 같지만 생각보다 많은 라이브러리에서 사용하고 있다!
//react에서 많이 쓰는 styled-components가 바로 tagged template를 활용한 것이다.
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
3. Boolean
논리적 참, 거짓을 나타내는 true, false이다. 조건문에 주로 사용 된다.
let number = 10;
console.log(number > 5); // true
console.log(number === 11); //false
4. undefined
undefined 타입의 값은 undefined가 유일하다. undefined는 변수를 초기화 할 때 사용된다. 즉, 개발자가 의도적으로 할당하기 위한 값이 아니라, 자바스크립트 엔진이 변수를 초기화하기 위해 사용하는 값으로, 변수를 참조했을 때, undefined가 나온다면, 변수가 선언 이후 한번도 값이 할당되지 않은 변수라는 것을 간파하기 위해 사용된다.
만약에 특정 변수가 값이 없다는 것을 표현하고 싶다면, 해당 변수에 undefined가 아닌 null을 할당하는 것이 undefiend를 의도에 맞게 사용하는 것이다.
5. null
null타입의 값은 null밖에 없다. 대소문자를 구분하니 유의하자. 프로그래밍에서 변수에 값이 없다는 것을 의도적으로 명시하기 위해 사용한다. 변수에 null을 할당하는 것은 변수가 이전에 참조하던 값이 있었는데 그 값을 더 이상 참조하지 않겠다는 의미이다. (이전에 값이 있었다!). null을 할당하면 자바스크립트 엔진은 해당 메모리 공간에 대해 가비지 콜렉션을 수행한다.
또한 함수가 유효한 값을 반환할 수 없는 경우 명시적으로 null을 반환하기도 한다.
const el = document.querySelector(".body-wrap");
console.log(el); // 클래스명이 body-wrap인 돔이 없다면 null을 반환
6. Symbol
ES6에서 추가된 타입으로, 변경 불가능한 원시 타입의 값이다. 다른 값과 중복 되지 않는 유일무이한 값이다. 주로 이름이 충돌할 위험이 없는 객체의 유일한 프로퍼티 키 값을 만들기 위해 사용한다. 심벌은 symbol
함수를 호출해 생성한다.
const Symbol('key');
console.log(typeof key); //symbol
const object = {};
object[key] = 'value입니다';
console.log(object[key]); // value입니다.
데이터 타입은 왜 있는 걸까?
- 데이터를 메모리에 저장하려면 먼저 확보해야할 메모리 공간의 크기를 결정해야 하는데, 타입으로 메모리 공간이 얼마나 필요한지 결정할 수 있다.
- 반대로, 타입을 알면 해당 값을 참조할 때 얼마만큼의 공간의 메모리 셀을 읽어야하는지도 알수 있다.
- 2진수로 저장되어 있는 값을 어떻게 해석 방식으로 해석할지도 타입에 의해 결정된다.
동적 타이핑
자바스크립트는 동적 타이핑 언어이다. 즉 한 번 변수에 값을 할당하여 타입이 지정되어 있어도, 다른 값을 할당하면 타입이 변한 값에 맞게 변경될 수 있다는 뜻이다. 동적 타이핑 언어는 정적 타이핑 언어와 다르게 변수 자체에 타입을 선언하지 않는다. 값이 할당될 때 값에 맞게 타입이 선언될 뿐이다(타입 추론).. 동적 타이핑은 유연성이 높아 편리하지만, 신뢰성은 떨어진다. 중간에 개발자도 모르게 타입이 바뀔 수도 있는 것이다.
let item = "실내화";
console.log(typeof item); //String;
item = 1004;
console.log(typeof item); //Number;