[블로깅] JavaScript의 자료형(Type)과 복사(Copy)

WAYPIL·2023년 3월 2일
0

코드스테이츠 부트캠프 프론트엔드 44기
Section 1 Unit 9 : [JavaScript] 핵심 개념과 주요 문법


1. 자료형


1.1. 원시 자료형

불변형 변수에 하나의 값(데이터)을 담는 타입을 말한다. 값 자체를 변경할 수 없으며, 변경하고 싶을 경우 새 값을 재할당해야 한다.

영문자를 대문자로 변환하는 string.toUpperCase() 같은 경우는 뭐냐고 물으신다면, 그건 래퍼 객체라는 개념이 동원된다. 실은 문자열 자체가 바뀌는 게 아니라, 래퍼 객체를 통해 재구성된 새 string이 반환되는 것이다.

종류는 string, number, boolean, undefined, null, symbol 등이 있다.


1.1.1. Undefined

undefined

  • [형용사] : 정의되지 않은, 확정되지 않은, 확실하지 않은

undefined란, JavaScript에서 '할당/지정되지 않은 값' or '못 찾겠는 값'을 표현하기 위해 사용되는 자료형을 말한다.


1.1.2 Null

null

  • [형용사] : 법적 효력이 없는, 값이 없는, 효과가 없는, 아무것도 포함되어 있지 않은

null이란, JavaScript에서 '의도적으로 비워둔 값'을 의미하는 자료형을 말한다. 때문에 Null을 쓸 자리에 Undefined를 쓸 경우 다소간의 혼란이 발생할 수 있다.

null의 타입은 당연히 null이지만, 실제 코드에서는 object라고 인식되니 주의해야 한다.

console.log(typeof null);  // object

JavaScript의 근본적인+고질적인 문제이기 때문에, object와 null 타입을 구분하기 위해서는 프로그래머가 수동으로 로직을 짜는 수밖에 없다. [230220] 일기 : typeof의 맹점 게시글을 참고.


1.2. 참조 자료형

불변형 변수에 힙(Heap: 가변형 데이터 저장소)으로 연결되는 주소(Reference)를 담고, 그 주소를 따라가면 값(데이터)들이 담긴 힙이 연결되어 있는 타입을 말한다.

종류는 object, function 등이 있다.

1.2.1. 특징

console.log( [1, 2, 3] === [1, 2, 3] );           // false
console.log( { foo: 'bar' } === { foo: 'bar' } ); // false

저 둘은 true가 아니다. 왜냐하면 주소가 다른 2개의 배열/객체라고 인식하기 때문이다. 형태가 똑같아도 주소가 다르면 서로 다른 거다.

여러분이 쌍둥이를 동일인물이라고 생각하지 않는 것과 같은 이치다.


1.3. 자료형이 아닌 것


1.3.1. array

array의 타입은 object이니 주의해야 한다. Python/C# 등의 언어에서 객체(딕셔너리)와 배열(리스트)를 다른 자료형으로 구분하는 것과는 대조적이다.

array와 object를 구분하는 코드를 짜는 법에 대해서는 [230220] 일기 : typeof의 맹점 게시글을 참고.


1.3.2. NaN

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

2. 복사

여기서 말하는 복사란, 같은 모양에 다른 주소인 참조 자료형을 생성하는 것을 말한다.


2.1. 얕은 복사 (Shallow Copy)

const arr = [1, 2, [3, 4]];
const copiedArr = [...arr];

console.log(arr === copiedArr);  // false
console.log(arr[2] === copiedArr[2]);  // true

위의 코드처럼 중첩된 참조 자료형들 중 '맨 위의 한 단계'만 복사하는 것을 말한다.

JavaScript에서 복사라고 하면 주로 이것을 말한다.


2.2. 깊은 복사 (Deep Copy)

중첩된 참조 자료형 모두를 복사하는 것을 말한다.

그러나 Pure JavaScript만으로는 깊은 복사를 수행할 수 있는 방법이 없다! 때문에 JSON을 이용하거나 외부 라이브러리를 이용해서 깊은 복사를 구현해야 한다.

2.2.1. 방법 1 - JSON.stringify() & JSON.parse

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로 바뀌게 되는 문제가 있다. 따라서 이건 완전한 방법이 아니다.

2.2.2. 방법 2 - lodash.cloneDeep()

외부 라이브러리인 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


<주의 사항>

이 게시물은 코드스테이츠의 블로깅 과제로 제작되었습니다.
때문에 설명이 온전치 못하거나 글의 완성도가 낮을 수 있습니다.

profile
Self-improvement Guarantees Future.

0개의 댓글