코드스테이츠 부트캠프 프론트엔드 44기
Section 1 Unit 9 : [JavaScript] 핵심 개념과 주요 문법
불변형 변수에 하나의 값(데이터)을 담는 타입을 말한다. 값 자체를 변경할 수 없으며, 변경하고 싶을 경우 새 값을 재할당해야 한다.
영문자를 대문자로 변환하는 string.toUpperCase() 같은 경우는 뭐냐고 물으신다면, 그건 래퍼 객체라는 개념이 동원된다. 실은 문자열 자체가 바뀌는 게 아니라, 래퍼 객체를 통해 재구성된 새 string이 반환되는 것이다.
종류는 string, number, boolean, undefined, null, symbol 등이 있다.
undefined
- [형용사] : 정의되지 않은, 확정되지 않은, 확실하지 않은
undefined란, JavaScript에서 '할당/지정되지 않은 값' or '못 찾겠는 값'을 표현하기 위해 사용되는 자료형을 말한다.
null
- [형용사] : 법적 효력이 없는, 값이 없는, 효과가 없는, 아무것도 포함되어 있지 않은
null이란, JavaScript에서 '의도적으로 비워둔 값'을 의미하는 자료형을 말한다. 때문에 Null을 쓸 자리에 Undefined를 쓸 경우 다소간의 혼란이 발생할 수 있다.
null의 타입은 당연히 null이지만, 실제 코드에서는 object라고 인식되니 주의해야 한다.
console.log(typeof null); // object
JavaScript의 근본적인+고질적인 문제이기 때문에, object와 null 타입을 구분하기 위해서는 프로그래머가 수동으로 로직을 짜는 수밖에 없다. [230220] 일기 : typeof의 맹점 게시글을 참고.
불변형 변수에 힙(Heap: 가변형 데이터 저장소)으로 연결되는 주소(Reference)를 담고, 그 주소를 따라가면 값(데이터)들이 담긴 힙이 연결되어 있는 타입을 말한다.
종류는 object, function 등이 있다.
console.log( [1, 2, 3] === [1, 2, 3] ); // false
console.log( { foo: 'bar' } === { foo: 'bar' } ); // false
저 둘은 true가 아니다. 왜냐하면 주소가 다른 2개의 배열/객체라고 인식하기 때문이다. 형태가 똑같아도 주소가 다르면 서로 다른 거다.
여러분이 쌍둥이를 동일인물이라고 생각하지 않는 것과 같은 이치다.
array의 타입은 object이니 주의해야 한다. Python/C# 등의 언어에서 객체(딕셔너리)와 배열(리스트)를 다른 자료형으로 구분하는 것과는 대조적이다.
array와 object를 구분하는 코드를 짜는 법에 대해서는 [230220] 일기 : typeof의 맹점 게시글을 참고.
NaN : Not a Number
- [번역] : 숫자가 아니다.
NaN(Not a Number)이란, JavaScript에서 잘못된 수식 따위로 인해 '계산 불가능함'을 나타내는 number 타입의 기호를 말한다.
주로 숫자와 문자를 연산하거나, 숫자가 아닌 값을 파싱하려 할 때 나타난다.
console.log(2 * 's'); // NaN
console.log(Number('a')); // NaN
절대 NaN에 비교 연산을 사용하면 안 된다! 무조건 false가 나오기 때문이다.
console.log(NaN == NaN); // false
console.log(NaN === NaN); // false
이 경우엔 isNaN() 내장 함수를 사용해야 한다.
console.log(isNaN(NaN)); // true
여기서 말하는 복사란, 같은 모양에 다른 주소인 참조 자료형을 생성하는 것을 말한다.
const arr = [1, 2, [3, 4]];
const copiedArr = [...arr];
console.log(arr === copiedArr); // false
console.log(arr[2] === copiedArr[2]); // true
위의 코드처럼 중첩된 참조 자료형들 중 '맨 위의 한 단계'만 복사하는 것을 말한다.
JavaScript에서 복사라고 하면 주로 이것을 말한다.
중첩된 참조 자료형 모두를 복사하는 것을 말한다.
그러나 Pure JavaScript만으로는 깊은 복사를 수행할 수 있는 방법이 없다! 때문에 JSON을 이용하거나 외부 라이브러리를 이용해서 깊은 복사를 구현해야 한다.
const arr = [1, 2, [3, function(){ console.log('hello world')}]];
const copiedArr = JSON.parse(JSON.stringify(arr));
console.log(arr); // [1, 2, [3, function(){ console.log('hello world')}]]
console.log(copiedArr); // [1, 2, [3, null]]
console.log(arr === copiedArr) // false
console.log(arr[2] === copiedArr[2]) // false
단, 참조 자료형에 '함수'가 포함되어 있을 경우 함수가 null로 바뀌게 되는 문제가 있다. 따라서 이건 완전한 방법이 아니다.
외부 라이브러리인 lodash를 설치하면 된다.
const lodash = require('lodash');
const arr = [1, 2, [3, function () { console.log('hello world') }]];
const copiedArr = lodash.cloneDeep(arr);
console.log(arr); // [ 1, 2, [ 3, [Function (anonymous)] ] ]
console.log(copiedArr); // [ 1, 2, [ 3, [Function (anonymous)] ] ]
console.log(arr === copiedArr) // false
console.log(arr[2] === copiedArr[2]) // false
<주의 사항>
이 게시물은 코드스테이츠의 블로깅 과제로 제작되었습니다.
때문에 설명이 온전치 못하거나 글의 완성도가 낮을 수 있습니다.