본문 바로가기

🚗 브라우저란?

인터넷 상에서 웹에 연결 시켜주는 윈도우 기반의 소프트웨어이다.
그 예로, 크롬, 파이어폭스, 사파리, 엣지 등을 브라우저라고 부른다.

🚗 브라우저 구성

사용자 인터페이스
주소 표시줄, 이전/다음 버튼, 북마크 메뉴 등

 

브라우저 엔진
사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어

 

렌더링 엔진
요청한 콘텐츠 표시.
예를 들어 HTML을 요청하면 HTML과 CSS를 파싱하여 화면에 표시함

 

통신
HTTP 요청과 같은 네트워크 호출에 사용됨

 

자바스크립트 해석기(엔진) ✔
자바스크립트 코드를 해석하고 실행한다.
브라우저마다 이 엔진이 다르다.

V8, Rhino, SpiderMonkey, Nashron 등이 있다.

 

UI 백엔드
콤보 박스와 창 같은 기본적인 장치를 그림.
플랫폼에서 명시하지 않은 일반적인 인터페이스로서, OS 사용자 인터페이스 체계를 사용

 

자료 저장소
이 부분은 자료를 저장하는 계층이다.
쿠키를 저장하는 것과 같이 모든 종류의 자원을 하드 디스크에 저장할 필요가 있다.

🚗 자바스크립트 엔진 구성

크게 메모리힙과 콜 스택으로 나뉜다.

 

메모리 힙(Memory Heap)
메모리 할당이 일어나는 곳

 

콜 스택(Call Stack)
코드 실행에 따라 호출 스택이 쌓이는 곳
함수 호출 시 호출 정보가 차곡차곡 쌓여있는 스택을 의미한다.

🚗 실행 컨텍스트란?

실행 가능한 JS 코드 블럭(함수)이 실행되는 환경을 의미한다.

 

개발자가 코드를 짜면, 어떤 코드 블록 안엔 변수 및 객체, 실행 가능한 코드가 있을 것이다.
이 코드를 실행하게 되면 실행 컨텍스트가 생성되고,
이 실행 컨텍스트들은 자바스크립트 엔진의 콜 스택에 차곡차곡 하나씩 쌓일 것이다.
이 때, 제일 위에 위치하고 있는 실행 컨텍스트가 현재 실행되고 있는 컨텍스트이다.

 

실행 컨텍스트가 생성되는 경우

  • 전역 코드
  • eval() 함수로 실행되는 코드
  • 함수 안의 코드가 실행될 경우
console.log ("This is global context"); // 1번

function ExContentxt1() {
    console.log("This is ExContent");
}

function ExContext2() { // 3번
    ExContext1();
    console.log("This is Context2");
}

ExContext2(); // 2번

1번: 전역 코드가 실행된다. 전역 코드가 실행되었으므로 실행 컨텍스트가 형성된다.

2번: 함수 안 코드가 실행되어 실행 컨텍스트가 실행된다.

3번: 함수 안의 함수 안 코드가 실행된 것이므로 실행 컨텍스트가 실행된다.

🚗 실행 컨텍스트 동작 과정

 

활성 객체 생성

실행 컨텍스트가 생성되면 JS 엔진은 해당 컨텍스트에서 실행에 필요한 여러 실행에 필요한 여러가지 정보를 담은 객체를 생성한다.

이를 활성 객체 라고 한다.

 

이 활성 객체는 앞으로 쓸 매개 변수나 사용자가 정의한 변수 및 객체를 저장하고 새로 만들어진 컨텍스트에 접근 가능하도록 만들어졌다.

이는 엔진 내부에 접근이 가능하다는 것이고, 사용자가 접근할 수 있다는 것이 아니다.

 

arguments 객체 생성

앞서 만들어진 활성 객체는 argument 프로퍼티로 이 arguments 객체를 참조한다.

 

예) 아래는 execute() 함수의 param1과 para2가 들어왔을 때를 도식화 한 것이다.

스코프 생성

컨텍스트가 생성되고 나면, 현재 컨텍스트의 유효 범위를 나타내는 스코프를 생성한다.

(스코프에 대한 자세한 설명은 이 게시글을 참조)

 

스코프 체인

이 스코프는 현재 실행 중인 실행 컨텍스트 안에서 연결 리스트와 유사한 형식으로 만들어 진다.

현재 컨텍스트에서 특정 변수로 접근해야할 경우, 이 리스트를 활용한다. 

이 리스트를 바로 스코프 체인 이라고 부른다.

 

스코프 체인은 [[scope]] 프로퍼티로 참조된다.

현재 생성된 활성 객체가 스코프 체인의 제일 앞에 추가된다.

 

변수 생성

현재 실행 컨텍스트 내부에서 사용되는 지역 변수의 생성이 이루어진다.

앞서 생성된 활성 객체가 변수 객체로 사용된다. 활성 객체와 변수 객체는 같은 객체이다.

 

변수 객체 안에서 호출된 함수 인자는 각각의 프로퍼티가 만들어지고 그 값이 할당된다.

 

값이 넘겨지지 않았을 경우 undefined가 할당된다.

함수에서 변수나 내부 함수는 단지 메모리에 생성만 한다.

초기화는 각 변수나 함수에 해당하는 표현식이 실행되기 전까지는 이루어지지 않는다.

따라서 변수들에는 undefined가 먼저 할당된다.

(표현식의 실행은 변수 객체의 생성이 다 이루어진 후 시작된다.)

 

this 바인딩

마지막 단계로, this 키워드를 사용하는 값이 할당된다.

여기서 this가 참조하는 객체가 없으면 전역 객체를 참조한다.

 

🚗 전역 실행 컨텍스트

전역 코드가 실행될 때 생성되는 컨텍스트가 전역 실행 컨텍스트다.

 

arguments 객체가 없다.

전역 실행 컨텍스트의 변수 객체가 전역 객체로 사용된다.

this를 전역 객체의 참조로 사용한다.

 

전역 실행 컨텍스트의 스코프 체인

var var1 = 1;
var var 2 = 2;

console.log(var1);
console.log(var2);

위코드 실행 시 먼저 전역 실행 컨텍스트로 생성이 되고, 변수 객체(활성 객체)가 만들어 진다.

이 변수 객체(활성 객체)의 스코프 체인은 자신이 최상위에 위치하는 변수 객체(활성 객체)이기 때문에

자기 자신만을 가진다.

즉, 변수 객체(활성 객체)의 [[scope]]는 변수 객체 자신을 가리키는 것이다.

그 후, var1, var2 변수들이 생성되고, 변수 객체에 의해 참조 된다.

🚗 스코프 체인 예제

var value = "value1";
function printFunc(){
 var value = "value2";
 function printValue(){
 return value;
 }
console.log(printValue());
}
printFunc();

불러올 함수가 어느 실행 컨텍스트에 위치하는지 파악하는 것이 가장 중요하다.

각 함수 객체가 처음 생성될 때 [[scope]]는 전역 객체의 [[scope]]를 참조한다.

따라서 함수 실행 시 생성되는 실행 컨텍스트의 스코프 체인엔

전역 객체 + 새로 만들어진 변수 객체가 추가되는 형태이다.

🚗 클로저

Closure.

직역하면 닫혀있다는 뜻이다. 

이미 생명 주기가 끝난 외부 함수의 변수(자유 변수)를 참조하는 것을 말한다.

즉, "닫혀있다"는 뜻은, 함수가 자유 변수에 닫혀있다는(엮여있다는) 뜻이다.

 

function outerFunc(){
 var x = 10;
 var innerFunc = function() { console.log(x);}
 return innerFunc;
}
var inner = outerFunc();
inner(); //10

innerFunc()의 [[scope]]는 outerFunc 변수 객체와 전역 객체를 가진다.

그런데 여기서 보면 innerFunc()는 outerFunc()이 끝난 뒤 실행된다.

그렇다면 outerFunc 실행 컨텍스트가 사라진 이후에 innerFunc 실행 컨텍스트가 생성되는 것이라 생각할 수 있다.

그러나 outerFunc 실행 컨텍스트가 사라졌더라도, outerFunc변수 객체는 여전히 남아있고, innerFunc의 스코프 체인으로 참조되고 있다.

이것이 자바스크립트의 클로저 개념이다.

 

 

Seize the day!

Spring MVC | Spring Boot | Spring Security | Mysql | Oracle | PostgreSQL | Vue.js | Nuxt.js | React.js | TypeScript | JSP | Frontend | Backend | Full Stack | 자기계발 | 미라클 모닝 | 일상