2024. 8. 16. 22:41ㆍ[Node.js_6기 본캠프 TIL]
▶데이터 타입(심화), 실행 컨텍스트, this
사전캠프부터 본캠프까지 통틀어 가장 개론적이고, 가장 어려운 강의를 들은 것 같다. 이해도가 아직 얕은 만큼, 이해한 부분까지만 정리해보려고 한다.
1. 데이터 타입의 종류(기본형과 참조형)
데이터 타입 중 기본형은 값이 담긴 주소값을 바로 복제하며, 참조형은 값이 담긴 주소값들로 이루어진 묶음을 가리키는 주소값을 복제한다. 이러한 복제의 특수성에 따라 기본형은 불변성을 가지며, 참조형은 불변성을 가지지 않는다. 우리가 흔히 함수식에서 값에 해당하는 Number, String, null 등이 기본형이며- 이 값들을 참고하는 함수인 Array, Function, Map 등이 참조형에 속한다.
쇼핑몰 회원 DB를 예시로 생각했을 때, 고객들이 가지고 있는 '기본' 정보들이 있고, 이것을 목적에 맞게 '참조'하는 명령어/분류가 있다고 외워보자.
2. 메모리와 데이터에 관한 배경지식
- 비트(bit): 컴퓨터가 이해할 수 있는 가장 작은 단위
- 바이트(byte): 8bit = 1byte
- 메모리(memory) : byte 단위로 구성. 흔히 아는 64bit는 8개의 byte로 분할하고, 각 byte를 메모리에 저장한다.
★ java 또는 c언어가 초기에 등장했을 때 숫자 데이터 타입은 크기에 따라 다양하게 지정해줘야 할 만큼 개발자가 handling 할 요소들이 많았다. 그러나 javascript의 경우, 높아진 컴퓨터 사양 등 다양한 상황이 겹쳐 해당 부분을 고려하지 않아도 된다.
- 변수 = 데이터
- 식별자 = 변수명
3. 변수 선언과 데이터 할당
대부분의 프로그램은 유지보수가 필수적인 만큼, 코드는 수없이 수정된다. 초기에 1002주소에 2byte의 데이터를 잡아놨는데, 8byte의 데이터를 밀어넣어야 한다면? 1003부터 이미 저장된 데이터들의 위치가 뒤로 밀리게 된다. 이 때문에 값을 바로 변수에 대입하지 않고 무조건 새로 만드는 방식을 선호한다.
똑같은 데이터를 여러번 불러와야 할 때, 매번 저장한다면 해당 작업에 필요한 공간이 매 순간 증식하게 된다. 예를 들어 10,000개의 변수에 '1'이라는 값을 동일하게 부여하기 위해 매번 저장한다고 생각해보자. 숫자는 항상 8byte로 고정되기 때문에, 1만개 * 8byte= 8만 byte. 그러나 한번만 저장하고, 이후에 불러올 때 그 주소값으로 가서 가져오게 한다면? 변수 영역에 해당하는 (2 byte 1만개 =)2만 byte + 데이터 영역 (8 byte 1개=) 8바이트 = 2만 8 byte 가 된다.
4. 기본형 데이터와 참조형 데이터
1) 메모리를 기준으로 다시한번 생각해보는 주요 개념
- 변수 : 변수 영역 메모리를 변경할 수 있음
- 상수 : 변수 영역 메모리를 변경할 수 없음
- 불변하다 : 데이터 영역 메모리를 변경할 수 없음
- 불변하지 않다 : 데이터 영역 메모리를 변경할 수 있음
2) 불변값과 불변성(with 기본형 데이터)
var a = 'abc'; 이고 'abc'가 @5003에 저장되었다고 할 때, a라는 변수가 abcdef가 되도록 수정하면 @5003이 업데이트 되는 것이 아니라 @5004에 'abcdef'가 추가되고 a는 해당 주소를 사용하게 된다. 기존의 'abc'는 더 이상 사용되지 않기 때문에 가비지컬렉터의 수거 대상이 된다.
3) 가변값과 가변성(with 참조형 데이터)
참조형 데이터는 별도 저장공간이 필요하다. 데이터 영역에 저장된 값은 계속 불변값이지만, 참조형 데이터를 위한 별도 영역은 얼마든지 변경하기 때문에 때문에 참조형 데이터를 흔히, ‘불변하지 않다(=가변하다)’라고 한다.
*) 중첩객체의 할당
자바스크립트에서 중첩객체란, 객체 안에 또 다른 객체가 들어가는 것을 말한다. 객체는 배열, 함수 등을 모두 포함하는 상위개념이기 때문에 배열을 포함하는 객체도 중첩객체라고 할 수 있다.
5. this(정의, 활용방법, 바인딩, call, apply, bind)
1) 상황에 따라 달라지는 this
this는 실행 컨텍스트가 생성될 때(함수를 호출할 때)결정되는데, 이것을 'this를 bind한다'고 표현한다. 전역 공간에서 this는 전역 객체를 가리키며, 런타임 환경에 따라 window(브라우저 환경) 또는 global(node 환경)를 각각 가리키기도 한다.
2) 메서드로서 호출할 때 그 메서드 내부에서의 this
함수와 메서드는 매우 비슷해보이지만, 독립성에서 차이를 보인다. 함수는 그 자체로 독립적인 기능을 수행하고, 메서드는 자신을 호출한 대상 객체에 대한 동작을 수행한다. 호출 주체를 명시할 수 없는 함수에서의 this는 전역 객체를 의미하고, 호출 주체를 명시할 수 있는 메서드의 경우 해당 객체를 의미한다.
ES6에서 처음 도입된 화살표 함수는, 실행 컨텍스트를 생성할 때 this 바인딩 과정 자체가 없다. 따라서, this는 이전의 값(상위값)이 유지된다.
* ES6에서는 함수 내부에서 this가 전역객체를 바라보는 문제 때문에 화살표함수를 도입되었다.
3) 콜백 함수 호출 시 그 함수 내부에서의 this
콜백함수 내부의 this는 해당 콜백함수를 넘겨받은 함수(메서드)가 정한 규칙에 따라 값이 결정된다. 콜백함수를 넘겨받은 함수에서 콜백 함수에 별도로 this를 지정한 경우는 예외적으로 그 대상을 참조하게 된다.
★ 문제로 익숙해지기) 어떤 매치가 성사될까?
하기의 코드를 브라우저에서 실행했을 때 나오는 결과를 보고, 해당 결과가 나오게 된 이유에 대해 자세히 설명하시오.
var fullname = 'Ciryl Gane'
var fighter = {
fullname: 'John Jones',
opponent: {
fullname: 'Francis Ngannou',
getFullname: function () {
return this.fullname;
}
},
getName: function() {
return this.fullname;
},
getFirstName: () => {
return this.fullname.split(' ')[0];
},
getLastName: (function() {
return this.fullname.split(' ')[1];
})()
}
console.log('Not', fighter.opponent.getFullname(), 'VS', fighter.getName());
console.log('It is', fighter.getName(), 'VS', fighter.getFirstName(), fighter.getLastName);
풀이)
// 1. fighter의 opponent에서 getFullname 값을 가져오라고 정확하게 호출했기 때문에, 'Francis Ngannou'가 찍힌다.
// 2. fighter의 getName을 불러오게 되면, fighter의 opponent가 아닌 fighter라는 객체에서 바로 fullname을 호출하기 때문에 'John Jones'가 찍힌다.
// 3. 화살표 함수는 바인딩을 하지 않기 때문에 최초에 선언된 fullname인 'Ciryl Gane'을 불러온다. 이 값에서 .split(' ')[0]이 붙었기 때문에 'Ciryl'만 찍힌다.
// 4. fighter.getLastName는 ()라는 호출부가 없기 때문에, 해당 부분은 fighter의 getLastName가 대체한다고 보면 된다.
// getLastName의 끝부분을 보면 ()로 바로 호출하는데, 주체가 명확하지 않으므로 전역객체를 바라보게 된다. 3번과 동일하되, .split(' ')[1]에 해당하는 'Gane'가 찍힌다.
'[Node.js_6기 본캠프 TIL]' 카테고리의 다른 글
[Node.js_6기 본캠프] Today I Learned_0820 (0) | 2024.08.20 |
---|---|
[Node.js_6기 본캠프] Today I Learned_0819 (0) | 2024.08.19 |
[Node.js_6기 본캠프] Today I Learned_0814 (0) | 2024.08.14 |
[Node.js_6기 본캠프] Today I Learned_0813 (0) | 2024.08.13 |
[Node.js_6기 본캠프] Today I Learned_0812 (0) | 2024.08.12 |