[JS] Type과 복사개념

Minyoung's Conference·2022년 10월 19일
0

JavaScript

목록 보기
18/28
post-thumbnail

값(원시) 타입(value type) - 각각의 고유한 메모리를 소유
참조 타입(reference type) - 생성된 인스턴스들은 주소값 공유

원시 타입과 참조 타입의 가장 큰 차이점

  • 원본이 바뀌면 참조 타입은 복사본도 같이 변경되지만, 원시 타입은 변경되지 않는다.
  • value type 객체들은 깊은 복사

원시 타입은 변하지 않음

let a = '원본 데이터';
let b = a; 

a = '원본 데이터 수정';

console.log(a); // output: 원본 데이터 수정
console.log(b); // output: 원본 데이터 

참조 타입은 변함

let obj1 = {name :'원본 데이터'}
let obj2 = obj1;

obj1.name = "원본 데이터 수정"

console.log(obj1)  //원본 데이터 수정
console.log(obj2)  //원본 데이터 수정


얕은 복사란? 
- 객체 복사 시, 해당 객체만 복사해 새 객체 생성
- 복사된 객체의 인스턴스 변수는 원본 객체의 인스턴스 변수와 같은 메모리 주소를 참조
- 따라서, 해당 메모리 주소의 값이 변경되면 원본 및 복사 객체의 인스턴스 변수값도 함께 변경
- Object.assign(), 전개연산자, slice() 등의 방법으로 얕은 복사 가능
- 전개연산자가 방법이 광범위하고 목적이 얕은 복사 목적이라 가장 명확한 코드
(const a = Object.assign(a객체,b객체), a = {a객체 , b객체}) 
- level 2(중첩된 구조)로 가면 독립적인 복사가 안됨.

깊은 복사란? 
- 객체 복사 시, 해당 객체와 인스턴스 변수까지 복사 (데이터 자체를 통째로 복사)
- 전부를 복사해 새 주소에 담기에 참조 공유 X (복사된 두 객체는 완전히 독립적인 메모리 차지)
- 객체가 참조 타입의 멤버를 포함할 경우 참조값의 복사가 아닌 참조된 객체 자체가 복사되는 것을 의미
	(원본의 참조는 더 이상 X)
- JSON.parse(JSON.stringify(객체)) 로 깊은 복사 가능하다고하지만 Math, Date 함수 못씀
- BigInt 또한 JSON.stringify로 객체 컨트롤 불가
- lodash 라이브러리 사용추천

*원시타입을 참조타입처럼 쓸 수 있는가?*

var name = "bit";
console.log(name.concat("coin"));
// "bitcoin" 이라는 결과가 나온다.

// 위의 원시타입을 concat 메서드를 이용해 사용했다.
// 풀어서 자바스크립트 내부의 엔진이 어떻게 돌아가는지 확인해보자.

var name = "bit";
var temp = new String(name);
console.log(temp.concat("coin"));
temp = null;

// new 를 붙이면 객체가 되기 때문에 원시타입을 객체로 바꾸어준다.
// 그리고 concat 메서드를 사용해 결과값을 똑같이 "bitcoin"으로 얻고
// 임시 변수 temp를 자동으로 지워준다.

//그러니 원시타입에 점 연산자를 이용해 집어 넣어봐야 값이 나오지 않는다. 
var name = "bit";
name.coin = "coin";
console.log(name.coin); // undefined

//위의 동작을 자바스크립트 엔진 입장에서 생각해보자.

var name = "bit";
var temp = new String(name);
temp.coin = "coin";
temp = null;

var temp = new String(name);
console.log(name.coin); // undefined

원시타입은 String, Number, Boolean, Null, undefined 가 있다.
참조타입은 원시타입을 제외한 나머지 데이터 타입이다.
원시 타입과 참조 타입의 가장 큰 차이는 
원시 타입은 값 자체가, 참조 타입은 데이터 주소가 저장된다는 것이다. 
원시 래퍼 타입은 String, Number, Boolean이 있다.
원시 래퍼 타입은 원시 타입을 참조 타입의 객체처럼 사용할 수 있도록 한다.

래퍼 객체 
- 내부적으로 문자열 값을 가지고 임시 객체로 변환
- 그리고 프로퍼티 접근이 종료되면 생성된 객체는 메모리에서 제거 (Boxing 이라 부름)
- 박싱 과정에서 생성되는 임시 객체를 래퍼 객체라고 함
- 문자열, 숫자, 불리언 타입만 존재
- 각 대응하는 네이티브 생성자로는 String(), Number(), Boolean()이 있음
- 여기서 주의할 점은 래퍼 객체는 원시타입과는 다르게 객체이다.
- js엔진 내부적으로 박싱 과정을 최적화하기 때문에 래퍼 객체를 생성해 사용할 일이 거의 없음
profile
안녕하세요, FE 개발자 김민영입니다.

0개의 댓글