PracticeEveryday
JavaScript 본문
변수의 타입
JavaScript에는 타입(Type : 형태 유형 종류)이라는 개념이 존재한다.
변수에는 다양한 타입이 있으며 타입에 따라 할 수 있는 일이 다르다!
원시 자료형 (Primitive :원시적인, 원어 Type)
객체가 아니면서 method를 가지지 않는다.
원시 자료형은 모두 '하나'의 정보 , 데이터를 담고 있다.
number : 3.141592
string : 'kim'
boolean : true | false
undefined : 변수가 정의되지 않았거나 값이 없다.
null : 의도적으로 비어있음을 표현하기 위해 null 이라는 것이 들어있다.
참조 자료형 (Reference : 참조 Type)
자바스크립트에선 원시 자료형이 아닌 모든 데이터는 참조 자료형이다.
참조형은 원시형 데이터의 집합이다.
배열 Array, 객체 Object, 함수 Function가 대표적이다.
참조 자료형은 기존에 고정된 크기의 보관함(변수)이 아니다.
참조 자료형을 변수에 할당 할 때에는 변수가 아닌 주소를 저장한다.
동적으로 크기가 변하기 때문에 변수가 아닌 다른 곳에 데이터를 저장하고 변수에는 그 주소에만 할당한다.
즉! 변수에는 하나의 값 혹은 주소만 저장할 수 있다.
const로 선언된 배열 변수에 Array.push를 적용 할 수 있는 이유!
-> 배열은 참조형이기 때문에 데이터의 주소를 대입할 수 있기 때문이다.
1. 값이 저장된 주소값을 할당한다.
2. 비어있는 데이터 공간을 확보하고 객체 속 프로퍼티에 대한 공간을 다시 확보한다.
3. 객체의 프로퍼티명과 주소를 매칭하고 확보했던 두 번째 주소에 데이터를 할당한다.
4. 변수를 선언하면 데이터가 담길 공간을 확보하고, 확보된 데이터의 주소값을 가지고 변수와 매칭시키는 과정은 동일하나 할당 과정에서 차이가 있다.
객체의 경우 상수로 선언해도 메모리값만 상수일 뿐 객체 안의 내용은 변경이 가능하다. 즉 객체가 저장된 공간을 가리키는 정보만 상수일뿐 그 객체의 정보 자체는 변경이 가능하다. 이런 이유로 JavaScript에서 객체는 변수로 선언할 이유가 없으며 거의 모든 케이스에서 상수로 선언하는게 일반적이다. 또 이렇게 상수로 선언된 객체의 Immutability를 보장하기 위해 여러 테크닉이 쓰이게 되는데 주로 ES6에서 도입된 Spread Operator를 사용하는 것이 일반적이다. 이렇게 객체를 복사하여 사용할 때도 Deep clone하지 않으면 의도치 않게 원본 객체가 변경되어버리기 때문에 많은 주의가 필요하다.
기본형과 자료형의 차이
1. 기본형은 값을 바로 그대로 할당하는 것이고 참조형에는 값이 저장된 주소값을 할당(참조)한다.
기본형
var a;
1. 변수 a를 선언하면 컴퓨터는 우선 메모리 안에 데이터를 담을 공간을 미리 확보합니다..
그림에서는 임의로 아래 표의 주소 313번 공간을 확보했습니다.
2. 확보한 주소값을 변수명 a와 매칭 시킵니다.
a = 10;
1. a에 값 10을 할당하라는 명령을 만나면 컴퓨터는 변수 a를 찾아와 변수 a와 매칭 되어 있는 주소 값인 @313을 읽고
그 주소로 이동해 그 공간에 10을 집어 넣습니다.
var b = 'abc'
1. 변수 b를 선언하고 문자열 abc를 할당시킵니다.
2. 데이터가 담길 314번의 메모리 공간을 확보하고 공간의 주소값을 가지고 변수명 b와 주소 @314에 매칭 시킵니다.
3. 다시 매칭된 주소의 314번으로 이동해 문자열 'abc'를 저장합니다.
4. ※ var b ='abc'라는 문장은 앞서 실행한 var a; a = 10'을 하나로 합쳐놓은 문장입니다.
선언 과정 : 공간을 확보하고 변수명과 주소를 매칭 시키는 과정
할당 과정 : 해당 변수가 가리키는 주소의 공간에 데이터를 저장하는 과정
b = false;
1. 다시 b에 false를 할당 하라고 하면 현재 가지고 있는 변수명들 중에 b가 있는지 검색합니다.
2. 만약 b를 찾지 못하면 앞서와 마찬가지로 변수 선언 과정을 하게 됩니다.
3. 현재 b는 메모리 상에 존재하기 때문에 b가 가리키는 주소(@314)값을 읽어 해당 주소 위치로 이동한 다음 그 자리에 false를 덮어쓰게 됩니다.
var c = b;
1. var 키워드로 인해 변서 선언 과정을 거치게 됩니다.
2. 빈 공간이 315번을 확보하고 구 주소를 변수 c와 매칭 시킵니다.
3. 314번으로 이동하여 b값인 false 값을 읽어 온 후 c의 315번 자리에 false를 넣게 됩니다.
여기서 중요한 것은 이렇게 저장된 기본형 데이터들은 그 자체로 비교가 가능 하다는 것입니다.
b가 가리키는 메모리 공간 상에 저장된 false와 c가 가리키는 메모리 공간상에 저장된 false는 완전히 같은 값입니다.
false라는 명칭 자체는 세상에 단 하나뿐인 키워드 입니다. 이 하나뿐인 단어를 이곳 저곳에서 사용하는 것입니다.
하나뿐인 단어를 서로 비교하니 항상 완전히 같다( b === c )가 true가 됩니다.
c = 20
1. 다시 c에 20을 할당하면 20을 가지고 c가 저장된 메모리 공간을 찾아서 원래 있던 false대신 20을 넣습니다.
2. 이 동작은 false란 값이 20으로 변하는 것이 아니라 메모리 공간에 있던 false 대신 20이란 값을 덮어 씌우는 것입니다.
3. 이제 b가 가리키는 값 false와 c가 가리키는 값 20은 서로 완전히 다른 값이 되었으므로 ( b !== c ) 가 true 입니다.
참조형
var obj = {
a : 1,
b : 'b'
};
1. 기본형 타입과 마찬가지로 메모리 공간을 확보하고 주소를 변수명과 매칭시키는 과정은 동일합니다.
2. 할당을 하려고 보니 그 값이 기본형이 아니고 참조형입니다.
참조형 데이터들은 프로퍼티(property)와 데이터, key : value로 묶인 쌍들로 이루어져 있습니다.
프로퍼티명은 변수와 비슷한 성질을 지니고 변수명과 실제 데이터는 주소값을 통하여 연결되어 있는데
프로퍼티와 데이터 사이에도 같은 동작을 하게 됩니다.
3. 우선 각 프로퍼티 명과 value가 담길 주소를 매칭하기 위해 공간을 새로 확보합니다.
여기선 임의의 1011번에 공간을 확보합니다.
4. 1012번에 a 프로퍼티의 value가 담길 공간을 확보하고 확보된 주소를 a 프로퍼티와 매칭합니다.
5. 이 후 1013번에 b 프로퍼티의 value가 담길 공간을 확보하고 그 할당된 주소의 1013번을 b 프로퍼티와 매칭시킵니다.
6. 이제 각각의 주소값마다 '기본형' 데이터값을 할당합니다.
=> 1012 에는 1을 1013에는 'b'가 저장됩니다.
7. 이제 앞서 어딘가에 저장되어 있을 객체 저장 정보의 주소를 즉, 여기서는 1011번을 413번에 매칭시키게 됩니다.
이러니 객체客體 客 손 객 體 몸 체
객지(客地)에 있는 몸. 생각과 행동의 목적물 주체에 대하여 작용의 대상이 되는 쪽라고 이름을 지었나보다!!!!
8. 이러한 과정을 데이터 공간의 기본형 데이터가 담길 때까지 반복합니다.
=> 참조형 데이터는 결과적으로 기본형 데이터들의 집합이라고볼 수 있습니다!!
var obj2 = obj
여기서 obj2를 obj에 할당하면?!?!!?
1. 414번 공간을 확보하고 obj2와 매칭시킨 다음 obj가 가리키고 있는 데이터인 1011번이라고 하는 주소를 obj2에 할당하게 됩니다.
이 과정이 참조가 이루어지는 과정입니다.
객체는 어딘가에 따로 저장되어 있는 그 객체가 저장된 주소만을 복사해온 것입니다.
obj2.a = 10;
obj의 a 프로퍼티에 10을 할당하려고 하면 obj2에 매칭된 414번 주소로 가 다시 1011번으로 이동한 다음 1011번 안에서 a프로퍼티를 찾고 a와 매칭되어 있는 1012번으로 이동하여 1대신 10을 넣게 됩니다.
414(변수: obj2에 매칭된 주소) => 1011(객체가 있는 주소) => 1012(객체의 a프로퍼티가 있는 주소)에 1대신 10을 넣음!
여기서 obj.a의 값 역시 10이 출력된다.
obj2 객체가 obj객체와 다른 새로운 객체를 만든 것이 아니라 본래 obj가 바라보던 객체를 함깨 바라보고 있기 때문에
obj === obj2// 완벽히 동일한 객체를 참조한다!
중첩된 객체 타입 nested : 중첩된
중첩된 객체 타입이란 참조형 데이터 안에 참조형 데이터가 있는 경우 nested 중첩되어 있다고 합니다.
var obj3 = {
a : [4, 5, 6]
};
obj3.a = 'new';
1. 공간을 확보하고 선언하는 과정은 동일합니다.
해당 표에서 1184번을 확보하고 확보된 해당 공간에 프로퍼티별 저장될 공간을 다시 확보합니다.
예제 코드에서는 a 프로퍼티가 하나뿐이므로 1185번을 a 프로퍼티가 저장될 공간으로 삼도록 하겠습니다.
2. 1185번에 a 프로퍼티 value를 할당하려고 보니 그 값이 인덱스로 이루어진 value 값들의 집합인 배열입니다.
배열도 객체
인덱스 0 : arr[0] ( value )
인덱스 1 : arr[1] ( value )
3. 1326 ~ 1328번까지 공간을 다시 확보하고 1185번에는 확보된 공간의 주소값들로 이루어진 배열이 들어갑니다.
4. 이 후 주소마다 value들을 대입합니다. 이번에는 요소들이 모두 기본형 데이터 이기에 더 이상의 공간 확보 작업을 하지 않습니다.
5. 대임을 모두 마무리하고 모든 데이터들에 대한 주소값 연결이 완료된 객체의 주소를 547번에 매칭시키는 것을 끝으로 obj3의 메모리 할당 작업이 마무리 됩니다.
obj.a = 'new'; // 'new'라고 하는 기본형 데이터를 obj3.a에 할당하려고 하면 어떻게 될까
1. 배열 자리에 순수 데이터 new 문장열이 들어옴으로써 1326~1328 데이터들은 링크가 사라지게 됩니다.
2. 주소를 참조하고 있는 곳이 어디에도 없어지게 되므로 가비지 콜렉터라고 불리는 메모리 청소기인 청소 대상에게 언젠가 사라지게 됩니다.
JS Basics #1 - JS 기본형과 참조형 차이점 정리
기본형과 자료형의 차이 자바스크립트의 두가지 타입인 기본형 과 자료형 의 정의에 대해 알아보고 두 타입간의 차이점이 발생하는 원인에 대해 알아보겠습니다. 자바스크립트 데이터 타입은
webclub.tistory.com
'JavaScript' 카테고리의 다른 글
JavaScript (0) | 2022.05.07 |
---|---|
JavaScript (0) | 2022.05.07 |
JavaScript (0) | 2022.05.04 |
JavaScript (0) | 2022.05.03 |
JavaScript (0) | 2022.05.02 |