1. 데이터타입의 종류 및 메모리
값의 저장 방식 & 불변성 여부에 따라 2가지로 나눔
(1) 기본형
: Number, String, Boolean, null, undefined, Symbol
- 값의 저장 방식 : 주소값 바로 복제
- 불변성 : 불변하다--> 메모리 관점에서 봐야함
(2) 참조형 (reference)
: Object > Array, Function, Date, RegExp, Map, Set
- 값의 저장 방식 : 주소값 묶음을 가르키는 주소값을 복제
- 불변성 : 불병성을 띄지 않음
* 메모리
(1) 비트 : 가장 작은 단위 (0과 1) :: 메모리를 구성하기 위한 작은 조각
(2) 바이트 : 8비트 = 1바이트
(3) 메모리 : 모든 데이터는 바이트 단위의 메모리 주소 -> 구분이 된다.
* 64비트 = 8바이트 (연속된 8개의 바이트에 저장)
* JS는 let -> 8 바이트 / c,java 는 byte (1), short(2), int(4), long(8)
# 식별자(변수명) & 변수(데이터) : var testValue(식별자) = 3 (변수)
2. 변수 선언과 데이터 할당 (기본형데이터)
let str ;
str = 'test!';
변수 영역 | 1002 | 1003 | 1004 |
이름 : str 데이터 : @5003 |
이름: 기본형 데이터 : @5003->5004 |
||
데이터 영역 | 5002 | 5003 | 5004 |
'test!' | 'test modify!!!' (데이터영역 변경 x 새로운 영역 줌:불변) |
* 값을 변수에 직접 대입 x, 주소를 저장함
- 자유로운 데이터 변환 & 효율적인 메모리 관리를 위해서
* 변수: 변수 영역 메모리 변경 가능
* 상수: 변수 영역 메모리 변경 불가능
* 불변하다 : 데이터 영역 메모리를 변경 불가능
* 불변하지 않다 : 데이터 영역 메모리 변경 가능
(1) 기본형 데이터
: 변수 영역에서 데이터를 변경하면, 데이터 영역의 주소가 변경되는것 뿐, 변경 불가능 > 불변하다
: 데이터가 (@5003 -> @5004로 변경 / @5003은 사용 안하니 가비지컬렉터 대상임)
3. 변수 선언과 데이터 할당 (참조형데이터) 변수복사의 비교
let obj ={
a:1 ,
b:'bbb'
}
//데이터 변형 : obj.a = 2
변수 영역 | 1001 | 1002 | 1003 |
obj / @7103~ | |||
데이터 영역 | 5001 | 5002 | 5003 |
1 | 'bbb' | 2 | |
★ obj 별도 영역 (참조형데이터) |
7103 | 7014 | 7015 |
a / @5001 > @5003으로 변경 |
b / @5002 |
* 참조형 데이터는 객체의 변수(프로퍼티)의 영역이 별도로 존재함
* 데이터 영역은 변경x, obj별도 영역 데이터가 변함 (@5001> @5003) = 불변하지 않다, 가변하다
#중첩객체
: 객체 안에 또 다른 객체
var obj ={
x:3,
arr : [3,4,5]
};
변수 영역 | 1001 | 1002 | 1003 |
obj @7103~ |
|||
데이터 영역 | 5001 | 5002 | 5003 |
3 | 4 | 5 | |
★ obj 별도 영역 | 7103 | 7104 | |
x @5001 |
arr @8104~ |
||
★ arr 별도 영역 | 8104 | 8105 | 8106 |
arr[0] @5001 |
arr[1] @5002 |
arr[2] @5003 |
* 참조 카운터 : 다른 곳에서 참조하거나 나타내지 않기에 0이 됨 > 가비지 컬렉터에 의해 메모리에서 제거
#변수 복사의 비교
let a = 10; //기본형
let obj1 = {c : 10, d: 'ddd'} //참조형
let b =a;
let obj2 = obj2;
//값 수정
b= 15;
obj2.c = 20;
변수 영역 | 1001 | 1002 | 1003 | 1004 |
a @5001 |
obj1 @8104~ (변함없음) |
b @5001 (복사) >@5003 (값 변경) |
obj2 @8104~ (변함 없음) |
|
데이터 영역 | 5001 | 5002 | 5003 | 5004 |
10 | 'ddd' | 15 | 20 | |
★ obj 별도 영역 | 8104 | 8105 | 8106 | 8107 |
c @5001 >@5004 (값 변경) |
d @5002 |
이렇게 되면 문제는,
obj2 (복사본) c의 값 = 20 // obj(원본) c의 값 = 20 (여기는 10이여야함)
* 기본형 : 복사 결과와 다른 값 ! (a = @5001 / b = @5003 )
* 참조형 : 복사 결과는 같은 값 ! (obj1 = @8104 / obj2 = @8104 )
해결방법은, 객체 자체를 변경하기! ( obj1 != obj2 )
obj.2= 20; 이 아닌 obj2 = { b: 20 , d : 'aaa'} 이렇게 새롭게 넣어주면 obj별도 영역이 새로 생김
변수영역
: 1004 -> obj = @8106
데이터 영역
: 5005 ('aaa')
★ obj 별도 영역
: 8106 (b: @5004 ) / 8107 (d:@5005)
4. 불변 객체 (얕은 복사 / 깊은 복사)
- 데이터 영역은 안 변하고, 객체 별도 영역만 변함 --> 불변 (데이터 영역)
(1) 객체의 속성(프로퍼티)에 접근
//user 객체 생성
let user = {
name: "홍",
age: 20
}
// 이름 변경하는 함수
// 입력값 : 변경 대상 user 객체, 변경할 이름
// 출력값 : 새로운 user 객체
// 특징 : 객체의 프로퍼티(속성)에 접근해서 이름 변경 --> 가변
// 객체의 속성 (newUser.name)으로 변경하면 "객체 영역의 주소값만 변경, 변수의 주소값 변경 x"
let changeName = function (user, newName){
let newUser = user;
newUser.name = newName; //박
return newUser;
}
// user2의 이름을 "박"으로 변경하려했지만, user1도 "박"으로 변함
// user2, user1이 속성만 바꾼걸로, 같은 주소값을 바라봄
let user2 = changeName(user, "박");
console.log(user.name, user2.name); //박, 박
console.log(user === user2); //true
(2) 새로운 객체를 반환
//user 객체 생성
let user = {
name: "홍",
age: 20
}
// 이름 변경하는 함수
// 입력값 : 변경 대상 user 객체, 변경할 이름
// 출력값 : 새로운 user 객체
// 새로운 객체를 반환 (프로퍼티 접근 x)
let changeName = function (user, newName){
return{ //새로운 객체 반환
name: newName,
age: user.age,
};
}
// user2가 새로운 주소값을 바라봄
let user2 = changeName(user, "박");
console.log(user.name, user2.name); //박, 홍
console.log(user === user2); //false
(3) 얕은 복사
- 중첩된 객체에 대해서는 완벽한 복사 불가능
- for(~in) : 반복하면서 1 deth만 가능 + 중첩된 곳은 메모리 복사를 할 수 밖에 없음
// 얕은 복사 패턴
let copyObject = function (객체명) {
let result ={};
for(let prop in 객체명){
result[prop] = 객체명[prop]
}
return result;
}
let user = { name :"홍", age : 20};
let user2 = copyObject(user);
user2.name = "박";
(4) 깊은 복사
: 재귀적 수행 (re+cursive : 다시 돌아간다 )
: 아래 코드 콘솔 찍으면서 공부해보
let copyObjectDeep = function(target) {
let result = [];
if(typeof target === 'object' && target != null){
for(var prop in target){
result[prop] = copyObjectDeep(target[prop]); //객체&&null 아니면 재귀적으로 다시 들어옴
}
}
else { result = target ;}
return result;
}
* JSON(= JavaScript Object Notation)을 이용하는 방법도 존재--> 참고만 하
[출처]
1. 스파르타 코딩, JavaScript 문법 종합반 3주차 (1강-4강)
'JavaScript' 카테고리의 다른 글
JS 4주차 정리 :: 콜백함수 | 동기 & 비동기 | promise | 제네레이터 및 | async await (2) | 2023.10.17 |
---|---|
JS 3주차 정리 :: 호이스팅 | 실행컨텍스트 | record | this | 콜백함수 | call, apply,bind (0) | 2023.10.16 |
JS 2주차 정리 :: ES6 문법 8가지 (구조분해할당, ...전개구문) | 일급객체 | Map | Set (1) | 2023.10.13 |
JS 1주차 정리 :: 데이터 타입 | 형 변환 | 화살표 함수 | 조건문 | 반복문 | 객체 | 배열 (0) | 2023.10.12 |
[모던 자바스크립트 Deep Dive] 27장. 배열(2) 배열 메서드 (1) | 2023.09.24 |