728x90
'원시타입, 객체타입, ... 어어 그니까 그게 무슨말인데? 내가 아는 원시는 원시인 우가우가 밖에 없단말이야.. '
별안간 울부짖던 나의 지난 날을 돌아보며 잊지 않기 위해 또 다시 기록 (아직 안지났을 수 있음)
데이터 타입을 알아보기 전에!
- 변수와 식별자
- 변수 : 변할 수 있는 데이터 ( ex : 숫자, 문자열, 객체, 배열 등)
- 식별자 : 어떤 데이터를 식별하는데 사용하는 이름 ( == 변수명)
- 변수 선언과 데이터 할당
var name;
// 변수 선언 : 변수 영역헤서 빈공간 (@1003)을 확보하고, 식별자를 name으로 지정
name = 'somyi';
// 데이터 할당 : 데이터 영역의 빈공간 (@5002)을 확보하고, 문자열 'somyi'를 저장
// 변수 영역에서 name 식별자를 검색해 (@1003)의 공간에 값으로 주소 (@5002)를 저장
name = 'some';
// 데이터 영역의 빈공간 (@5003)을 확보하고, 문자열 'some'를 저장
// 변수 영역에서 name 식별자를 검색해 (@1003)의 공간에 값으로 주소 (@5003)을 저장
데이터의 타입의 종류
원시형(기본형)
- 종류 : 숫자(number), 문자열(string), 불리언(boolean), null, undefined, symbol
- 할당 / 연산 시에 값이 복제
- 불변성 (call by value)
// 위의 변수 선언과 데이터 할당의 예시 코드를 계속 이어가겠습니다!
name = 'some';
// 변수 영역의 식별자를 name을 갖는 @1003 공간에 값으로 주소 (@5003)을 저장
var nickname = name;
// 변수 영역의 빈공간 (@1004)을 확보하고 식별자를 nickname으로 지정
// 변수 영역에서 식별자 name을 검색하여 저장된 값인 주소 (@5003)을 @1004의 값으로 저장
name = 'koung';
// 변수 영역의 식별자를 name을 갖는 공간(@1003)에 값으로 주소 @5004를 저장
console.log(nickname); // 콘솔에 'some'이 출력
// nickname을 식별자로 갖는 공간(@1004)의 값은 여전히 주소 @5003이기 때문
참조형
- 종류 : object, array, function, date, regexp …
- 할당 / 연산 시에 값이 참조
- 주솟값을 복제하기 때문에 주솟값만 불변성이고 실제 데이터는 가변적 (call by reference)
// 어째서..주솟값만 불변성이고 실제 데이터는 가변적인거지?
var person = {
name : 'somyi lee',
age : 28
};
// 변수 영역의 빈 공간 (@1006)을 확보하고, 그 공간의 식별자를 person으로 지정
// 각 프로퍼티를 저장할 변수영역을 마련하고 그 영역의 주소(@7103~?)를 데이터 영역의 빈 공간 (@5001)에 저장
// 객체 @5001의 변수 영역에서 빈 공간 (@7103, @7104)에 식별자를 각각 name, age로 지정
// 데이터 영역의 빈 공간 (@5002, @5003)에 문자열 'somyi lee'와 숫자 28을 저장
// 앞서 저장한 문자열과 숫자의 주소값(@5002, @5003)를 @7103과 @7104에 각각 저장
var personInfo = person;
// 변수 영역의 빈 공간 (@1007)을 확보하고, 그 공간의 식별자를 personInfo로 지정
// 변수 영역에서 person이라는 식별자를 검색하여 저장된 값인 주소 (@5001)을 @1007의 값으로 저장
person.age = 26;
// 데이터 영역의 빈 공간 (@5004)에 숫자 26을 저장
// 객체 @5001의 변수 영역에서 age라는 식별자를 검색 (@7104)
// @7104에 앞서 저장한 숫자의 주소 (@5004)를 값에 저장
console.log(personInfo.age); // 26
// personInfo이라는 객체가 바라보고 있는 주소는 여전히 @5001이고, 객체의 내부 값만 바뀐 것 이므로 26이 콘솔에 출력
여기서 내가 궁금했던 점 🤔
Q. 객체는 가변적인 데이터 타입이다. 그치만 불변하는 객체가 필요하다면?
- 해결 방법
1. 기존 정보를 복사해서 새로운 객체를 반환하는 함수를 만든다.
2. copyObject()를 사용한다. - 문제점
1. 시스템적 제약이 없다.
2. 얕은 복사만을 수행한다.
Q. 얕은 복사만을 수행하는게 왜 문제점이야?
- 얕은 복사와 깊은 복사에 대해 먼저 알아보자!
- 얕은 복사
: 바로 아래 단계의 값만 복사 (내부 객체의 값은 복사되어 새로운 데이터가 만들어 지지 않고 기존 데이터를 그대로 참조)
: 원본과 복사본은 동일한 메모리 주소를 참조하고 있기 때문에 한쪽에서 객체를 수정하면 다른 쪽에서도 동일한 변경이 반영 - 깊은 복사
: 내부의 모든 값을 찾아서 전부 복사(독립적인 새로운 객체를 생성하여 복사본은 원본과 다른 메모리 주소를 참조)
: 한쪽에서 객체를 수정해도 다른 쪽에는 영향을 주지 않아 두 객체는 완전히 독립적으로 동작
- 얕은 복사
- 그래서 얕은 복사만 수행하는게 왜 문제라고?
- 불변객체가 필요해서 복사를 수행했는데, 복사본과 원본이 서로 영향을 주고받는다면 복사를 수행한 의미가 없을 것이다.
때문에 완전히 원본으로부터 완전히 독립적인 객체를 생성하고 싶을땐 깊은 복사를 사용하는 것을 추천!
* 깊은 복사 수행 : JSON.stringify(), JSON.parse(), Lodash의 cloneDeep() 메서드 등...
- 불변객체가 필요해서 복사를 수행했는데, 복사본과 원본이 서로 영향을 주고받는다면 복사를 수행한 의미가 없을 것이다.
- 그럼 얕은 복사는 왜 있는거야?
- 원본과 복사본이 메모리를 공유하여 사용함으로써 메모리 사용량을 줄이기 때문에 효율적이며 성능상의 이점을 제공한다.
- 서로 다른 객체를 서로 연결하여 변경 사항을 상호간에 공유하고 싶을때 효율적이다.
글을 마치며
주로 인풋 값을 핸들링 하거나, 서버에서 넘어오는 데이터를 가공할 때 예기치 못한 값이 들어가 있을 때가 왕왕 있었다.
또, a와 b는 분명 같은 값을 갖고 있는데 왜 a === b는 false인지 이해 못 할 때가 많았다
그럴 때 마다 컴퓨터랑 씨름하며 왜 ... 왜...!! 왜 내가 예상한 값을 주지 않는거야? 라고 원망도 해보고 애원도 해봤었는데
컴퓨터가 들어줄리가 ㅎ
이제서야 그동안 갖고 있던 의문점들이 조금씩 풀려 나가는 것 같아 속이 시원하다.
공부하며 분명 틀린 부분이나 허술한 부분이 있겠지만, 더 찾아보고 공부하다보면 컴퓨터에 가까워지는 날이 오지 않을까?
언젠간 나의 소듕한 컴퓨터씨와 컴아일체 되는 날을 기대해본다. 기다려라 ^ㅡ^
'Weekly I Learned > JavaScript' 카테고리의 다른 글
실행 컨텍스트 뿌셔뿌셔(작성중김성중) (1) | 2023.07.19 |
---|---|
TypeScript 왜 써야할까? (0) | 2023.06.12 |
JavaScript 동작 원리... (0) | 2023.06.08 |