기술 면접 대비를 위해 주요한 개념을 복습하고, 나의 말로 정리를 해본다.
자바스크립트 비동기 처리 과정 & Event Loop
자바스크립트 엔진은 기본적으로 하나의 Thread에서 동작함
하나의 Thread === 하나의 Stack === 동시에 단 하나의 작업만 할 수 있다
자바스크립트 엔진은 하나의 코드 조각을 하나씩 실행, 비동기적으로 이벤트를 처리하거나 Ajax 통신을 하는 작업은 사실상 Web API에서 모두 처리
자바스크립트가 동시에 단 하나의 작업만 한다고 하는데, 어떻게 여러가지 작업을 비동기로 할 수 있을까?
→ Event Loop와 Queue 덕분
이벤트루프는 반복해서 Call Stack과 Queue 사이의 작업을 확인하고, Call Stack이 비워진 경우 Queue에서 작업을 꺼내 Call Stack에 넣어준다.
자바스크립트는 이 Event Loop와 Queue를 이용해 비동기 작업을 수행한다. 직접적인 작업은 Web API에서 처리되고, 그 작업들이 완료되면 요청시 등록했던 Callback이 Queue에 등록된다.
이벤트루프는 Stack에 처리할 작업이 없을 경우 우선적으로 Microstack Queue를 확인한다. 작업이 있으면 꺼내서 Call Stack에 넣고, 비어있으면 Task Queue를 확인하고 작업을 Call Stack에 넣는다.
이런식으로 이벤트루프와 Queue는 자바스크립트 엔진이 하나의 코드 조각을 하나씩 처리할 수 있도록 작업을 스케줄하고 자바스크립트에서 비동기 작업을 수행할 수 있도록 해준다.
https://sculove.github.io/post/javascriptflow/
Hoisting
호이스팅은 코드가 실행하기 전 **변수선언/함수선언**이 해당 스코프의 최상단으로 끌어 올려진 것 같은 현상
호이스팅? ‘선언이 먼저 메모리에 저장되었다.’는 것을 의미.
- 변수 생성 과정
- 선언 단계 - 변수를 실행 컨텍스트의 변수 객체에 등록 var x
- 초기화 단계 - 변수 객체에 등록된 변수를 위한 공간을 메모리에 확보. undefined로 초기화.
- 할당 단계 - undefined로 초기화된 변수에 실제 값을 할당함 var x = 100;
- var 키워드로 선언된 변수는, 선언과 함께 undefined로 초기화되어 메모리에 저장 → 호이스팅이 일어나고, undefined로 반환됨.
- let, const 키워드로 선언된 변수는 선언과 초기화 단계가 분리되어 진행됨 → 초기화 이전에 변수 접근시 호이스팅이 일어나지만, 참조 에러 발생. (아직 메모리 공간이 확보되지 않고, TDZ(Temporal Dead Zone)에 위치)
변수가 함수 내에서 정의되었을 경우 선언이 함수의 최상위로,
함수 밖에서 정의되었을 경우 전역 컨텍스트의 최상위로 변경된다.
끌어올려지는 것은 선언.
var x = 100; 구문이라면 var x 가 호이스트 되는 것.
선언문은 항상 자바스크립트 엔진 구동시 최우선으로 해석하므로 호이스팅 됨
foo( );
function foo( ){
console.log(‘hello’);
};
// console> hello
할당문은 런타임 과정에서 이루어지기 때문에 호이스팅 되지 않음
foo( );
var foo = function( ) {
console.log(‘hello’);
};
// console> Uncaught TypeError: foo is not a function
Scope
자바스크립트는 전통적으로 함수 레벨 스코프 지원해옴
ES6부터 블록 레벨 스코프도 지원하는 렉시컬 스코프 규칙을 따름
**렉시컬 스코프(Lexical Scope)**는 함수를 어디에 선언했는지에 따라 상위 스코프가 결정되는 것(정적 스코프라고도 함)
함수 레벨 스코프 - 함수 내부 전체에서 유효한 식별자가 됨
- var 키워드로 선언된 변수
- 함수 선언식으로 만들어진 함수
블록 레벨 스코프 - 블록 내부에서 참조, 그 밖의 영역에서는 잘못된 참조로 에러 발생
- let, const 키워드로 선언된 변수
Closure
클로저는 두 개의 함수로 만들어진 ‘환경(Lexical Scope)’으로 이루어진 특별한 객체의 한 종류
여기서 환경이란, 클로저가 생성될 때 그 범위에 있던 여러 지역 변수들이 포함된 context를 의미
이 클로저를 통해 자바스크립트에는 없는 비공개 속성/메소드, 공개 속성/메소드를 구현할 수 있는 방안을 마련할 수 있다.
클로저 생성 조건
- 내부 함수가 익명 함수로 되어 외부 함수의 반환값으로 사용됨
- 내부 함수는 외부 함수의 실행환경(execution environment)에서 실행됨
- 내부 함수에서 사용되는 변수는 외부 함수의 변수 스코프에 있음
function outer() {
var name = `closure`;
function inner() {
console.log(name);
}
inner();
}
outer();
// console> closure
var name = `Warning`;
function outer() {
var name = `closure`;
return function inner() {
console.log(name);
};
}
var callFunc = outer();
callFunc();
// console> closure
위 코드에서 클로저는 callFunc
callFunc 호출에 의해 name이라는 값이 콘솔에 찍히는데, 찍히는 값은 Warning이 아닌, closure라는 값. 즉, outer 함수의 context에 속해있는 변수를 참조한다. 여기서 outer 함수의 지역변수로 존재하는 name 변수를 free variable(자유변수) 라고 한다.
https://meetup.nhncloud.com/posts/86
이처럼 외부 함수 호출이 종료되어도, 외부 함수의 지역 변수 및 변수 스코프 객체의 체인 관계를 유지할 수 있는 구조를 클로저라고 한다. 다시 말해, 외부 함수에 의해 반환되는 내부 함수를 가리킨다.
'JavaScript' 카테고리의 다른 글
자바스크립트 엔진의 동작 원리 (0) | 2023.10.14 |
---|---|
[JavaScript] 자바스크립트에서 this란? (0) | 2023.10.04 |
[JavaScript] 얕은 복사(Shallow copy)와 깊은 복사(Deep copy) (0) | 2023.09.20 |
[JavaScript] == 와 === 의 차이 (0) | 2023.09.19 |
DFS(Depth-First Search) : 재귀함수와 스택 프레임 (0) | 2023.08.05 |