티스토리 뷰

With. 지그 (@zigsong)

소요시간: 1시간 45분

Q1.

원시 타입과 참조 타입 데이터가 메모리에 할당되는 과정을 이야기해봐요.

원시 타입 데이터

원시타입

참조 타입 데이터

객체타입참조타입 서술

Q2.

자바스크립트의 콜스택과 힙에는 각각 어떤 것들이 저장될까요? 그리고 자바스크립트는 왜 힙이라는 별도의 메모리 공간을 가질까요?

콜스택

  • 원시타입 데이터가 저장된다.
  • 실행 컨텍스트를 통해 변수 식별자 저장, 스코프 체인 및 this 관리, 코드 실행 순서 관리 등을 수행

메모리 힙

힙을 왜 쓰는가?

  • 참조 타입 데이터의 프로퍼티를 동적으로 변경하는 것이 가능하도록 하기 위함이다. 스택을 사용하면 중간에 값이 변경될 때마다 변경된 값 이후의 데이터들의 위치를 같이 이동시켜야 한다. 힙을 사용하여 동적으로 메모리를 할당하면 이같은 상황을 예방할 수 있다.
  • 런타임 시에 메모리의 크기를 동적으로 결정할 수 있다.

Q3.

자바스크립트에서 호이스팅은 왜 일어나는 걸까요?

자바스크립트가 소스 코드를 2단계로 나누어 실행하기 때문이다.

  1. 선언문들을 찾아 변수 등을 실행 컨텍스트의 렉시컬 환경에 등록한다.
  2. 소스코드를 첫줄부터 차례로 실행하며 값을 할당하고 참조한다.

Q4.

var, let, const의 호이스팅은 어떠한 차이가 있을까요? 그리고 TDZ는 무엇일까요?

  • var: 선언 단계와 초기화 단계가 동시에 이루어짐.
  • let: 선언 단계와 초기화 단계가 분리되어 진행된다.
  • const: 선언 단계와 초기화 단계가 분리되어 진행된다, const로 선언된 변수는 반드시 선언과 동시에 초기화해야한다

TDZ

일시적인 사각지대

  • 스코프의 시작 지점부터 초기화 시작 지점까지의 구간
  • 선언 단계(Declaration phase) : 변수를 실행 컨텍스트의 변수 객체에 등록하는 단계를 의미한다. 이 변수 객체는 스코프가 참조하는 대상이 된다.
  • 초기화 단계(Initialization phase) : 실행 컨텍스트에 존재 하는 변수 객체에 선언 단계의 변수를 위한 메모리를 만드는 단계이다. 이 단계에서 할당된 메모리에는 undefined로 초기화 된다.
  • 할당 단계(Assignment phase) : 사용자가 undefined로 초기화된 메모리의 다른 값을 할당하는 단계이다.

지그 질문에 대한 정리

Q1. var, let, const

Q1-1. 각각의 스코프는 어떻게 정의되나요?

var: 함수 레벨 스코프, 따라서 함수 외부에서 var 키워드로 선언한 변수는 모두 전역 변수가 된다.

let, const: 블록 레벨 스코프

📌 let과 const는 호이스팅이 발생하지 않는 것처럼 보이지만 호이스팅은 발생한다. 이는 선언 단계와 초기화 단계 사이의 TDZ에 의해 호이스팅이 발생되지 않는 것처럼 보인다. (내 질문 중 4번 참고)

Q1-2. 각 경우 변수는 언제 메모리에 할당되나요?

(내 질문 중 4번 참고)

Q2. 다음의 두 코드는 어떤 차이가 있나요?

// 1번
const str1 = 'abc';
const arr1 = [1,2,3,4]
const obj1 = {1: 'a', 2: 'b', 3: 'c' }

// 2번
const str2 = new String('abc');
const arr2 = new Array([1,2,3,4])
const obj2 = new Object({ 1: 'a', 2: 'b', 3: 'c' })

2번코드는 생성자 함수를 사용하여 인스턴스를 생성한다.

'zig'.toUpperCase(); // 'ZIG' -> How is it Possible?

원시값은 객체가 아니므로 프로퍼티나 메서드를 가질 수 없는데도 원시값인 문자열이 마치 객체처럼 동작한다. 이는 원시값인 문자열, 숫자, 불리언 값의 경우 이들 원시값에 대해 마치 객체처럼 마침표 표기법(또는 대괄호 표기법)으로 접근하면 자바스크립트 엔진이 일시적으로 원시값을 연관된 객체로 변환해 주기 때문이다. 즉, 원시값을 객체처럼 사용하면 자바스크립트 엔진은 암묵적으로 연관된 객체를 생성하여 생성된 객체로 프로퍼티에 접근하거나 메서드를 호출하고 다시 원시값으로 되돌린다. 이처럼 문자열, 숫자, 불리언 값에 대해 객체처럼 접근하면 생성되는 임시 객체를 래퍼 객체라고 한다.
[Javascript] 래퍼 객체 (Wrapper object)

Q3. null과 undefined에는 어떤 차이가 있나요?

null은 JavaScript의 원시 값 중 하나로, 어떤 값이 의도적으로 비어있음을 표현하며 불리언 연산에서는 거짓으로 취급합니다.

null은 식별되지 않은 상태를 나타내며 해당 변수가 어떠한 객체도 가리키고 있지 않음을 표시한다. 변수에 null을 할당하는 것은 변수가 이전에 참조하던 값을 더 이상 참조하지 않겠다는 의미다. 이는 이전에 할당되어 있던 값에 대한 참조를 명시적으로 제거하는 것을 의미하며, 자바스크립트 엔진은 누구도 참조하지 않는 메모리 공간에 대한 가비지 콜렉션을 수행할 것이다.

선언하지 않은 식벽자를 typeof 연산자로 연산해 보면 ReferenceError가 발생하지 않고 undefined를 반환한다.

typeof undeclared; // undefined

undefined는 원시값으로, 선언한 후 값을 할당하지 않은 변수 혹은 값이 주어지지 않은 인수에 자동으로 할당됩니다.

undefined는 개발자가 의도적으로 할당하기 위한 값이 아니라 자바스크립트 엔진이 변수를 초기화 할 때 사용하는 값이다. 따라서 개발자가 의도적으로 undefined를 변수에 할당하는 것은 undefined의 본래 취지와 어긋날뿐더러 혼란을 줄 수 있으므로 권장하지 않는다. 이러한 경우에는 null을 할당한다.

Q4. typeof와 instanceof는 각각 언제 사용해야 할까요 ?

2번 질문의 연장선

const str1 = 'abc';
const str2 = new String('abc');

console.log(str1 instanceof String); // false
console.log(str2 instanceof String); // true

왜 이런 결과가 나올까요?

A. str2는 생성자 함수로 만들어진 객체이기 때문이다.

typeof 연산자는 피연산자의 평가 전 자료형을 나타내는 문자열을 반환합니다.

instanceof 연산자는 생성자의 prototype 속성이 객체의 프로토타입 체인 어딘가 존재하는지 판별합니다.

기타 인사이트

동적 타이핑

자바스크립트의 변수는 선언이 아닌 할당에 의해 타입이 결정(타입 추론)된다. 그리고 재할당에 의해 변수의 타입은 언제든지 동적으로 변할 수 있다. 더욱이 자바크립트는 개발자의 의도와는 상관없이 자바스크립트 엔진에 의해 암묵적으로 타입이 자동으로 변환되기도 한다. 결국 동적 타입 언어는 유연성은 높지만 신뢰성은 떨어진다.

'스터디 > 하브루타 스터디' 카테고리의 다른 글

7. Scope and Closure  (0) 2021.05.09
6. This  (3) 2021.05.02
4. 함수  (0) 2021.04.18
3. 비동기  (1) 2021.04.12
2. CSS selector  (0) 2021.04.04