[앨리스 IoT 1기 부트캠프] 3주차 실행 컨텍스트

Minha Sohn·2022년 12월 19일
0

수강목표

  1. 자바스크립트의 필수적인 문법을 이해할 수 있다.

    기초적인 자바스크립트 문법에 더해, 깊은 이해를 요구하는 자바스크립트의 문법을 이해한다.

  2. HTML, CSS, JS로 프로젝트를 구현할 수 있다.

    간단한 프론트엔드 프로젝트를 구성하고 구현한다.

  3. 자바스크립트의 내부 동작에 대해 이해할 수 있다.

    비동기 처리, 변수 생명주기 등의 내부 동작에 대해 이해한다.


자바스크립트 비동기

자바스크립트는 다른 멀티스레드 프로그래밍 언어와 다르게 싱글 스레드 환경에서 비동기 동작을 처리한다. 싱글 스레드 비동기 환경을 구성하는 중요 요소 중 하나인 이벤트 루프에 대해 이해하면, 자바스크립트 엔진 레벨에서의 비동기 코드 동작을 이해할 수 있따. 복잡한 비동기 동작을 이해하고 높은 수준의 비동기 코드를 작성하며, 버그의 원인을 파악할 수 있게 된다.

동기적 환경
어떤 특정 시점에 단 하나만을 실행하고 있다는 것을 의미한다. 프로그램의 실행흐름이 코드의 실행 흐름과 같다는 뜻이다.


1. 자바스크립트 함수가 실행되는 과정

자바스크립트 실행

자바스크립트는 흔히 인터프리터(intepreter) 언어라고 말하지만 컴파일 언어의 면모가 있다. 자바스크립트 컴파일은 여러 단계로 구성되며, 각 단계별로 코드를 처리하는 목적이 다르다.

인터프리터 언어
코드를 실행시키면 그때 마다 한줄 한줄 읽어나가며 기계어로 변환시키는 언어이다.
컴파일 언어
미리 모든 코드를 기계어로 번역 해놓고 실행한다. 인터프리터 언어보다 빠르다는 장점이 있다.

자바스크립트의 컴파일 과정을 이해하면 코드가 선언되고 실행될 때 생기는 버스, 메모리 릭(Memory Leak)을 이해하고 고칠 수 있다.

어떠한 코드도 없는 경우

자바스크립트 엔진은 코드가 없는 경우에도 아래의 3가지 값을 초기화 시킨다.

  • this
  • 변수 객체 (Variable Objects)
  • Scope Chain

this: window

this 는 코드가 실행되는 시점에 가리키는 객체를 말한다.
현재 어떠한 코드도 없고 global scope에 속하기 때문에 this가 가리키는 객체는 window가 될 것이다.
window는 브라우저에 존재하는 최상위 객체이다.

변수 객체 (Variable Object)와 scope chain

코드가 없으니 변수 객체는 빈 값을 출력하고, scope chain은 global 전역객체 하나 밖에 없기 때문에 빈 칸으로 출력된다.
변수 객체 (Variable Object): {} scope chain" []

정리 하자면,

  • 자바스크립 엔진은 코드가 없어도 실행 환경 (실행 컨텍스트)을 초기화 한다.
  • 스코프(scope) 는 코드가 현재 실행되는 환경, 맥락(context)을 의미한다.
  • this는 스코프에 저장된 변수들, 스코프 체인 등이 환경에 포함된다.
  • this의 경우, 글로벌 스코프에서는 window를 가리킨다.

특정 함수가 있는 경우

function myFunc() {
	let a = 10;
  	let b = 20;
  	function add(first, second) {
    	return first + second
    }
  return add(a,b)
}

myFunc()

myFunc 함수가 실행되고 있을 때

  • this: undefined (strict mode)
  • variable object: let a = 10; let b = 20; add: function {...}
  • scope chain: [global]

myFunc 함수가 끝이 났을 때

  • this: window
  • variable object: {}
  • scope chain: []

add 함수가 실행 될때

  • this: undefined
  • variable object: { first: 10 second: 20 }
  • scope chain: [myFunc, global]
    add 함수 바로 위에 있는 스코프가 myfunc, myfunc 위에 있는 스코프가 global 이다.

정리하자면,

  • 함수가 실행되면, 함수 스코프에 따라 환경이 만들어진다.
  • this, 함수 스코프의 변수들, 그리고 스코프 체인이 형성된다.
  • 스코프 체인을 따라 글로벌 환경에 도달한다.
  • 객체의 메소드가 호출 되는 경우, 메소드의 this는 메소드가 실행되는 해당 객체를 가리키게 된다.
  • 하지만 this가 가리키는 것은 환경에 따라 변할 수 있다.

2. 실행 컨텍스트 (Execution Context)

실행 컨텍스트틑 자바스크립트 코드가 실행되는 환경을 말한다.
코드에서 함조하는 변수, 객체 (함수 포함), this 등에 대한 레퍼런스가 있다.

자바스크립트 엔진이 코드를 실행할 떄 전역 실행 컨텍스트(global execution context)를 먼저 만들고, 함수가 호출될 때 함수의 실행 컨텍스트(function execution context) 를 차례대로 만들어 순서대로 callstack에 쌓이게 된다.

그래서 callstack을 실행 컨텍스트의 스택이라고도 한다.

  • 전역에 존재하는 코드는 함수나 클래스 내부의 코드를 무시하고 컨텍스트를 가진다.
  • 함수에 존재하는 코드는 함수 내부에서만 컨텍스트를 가진다.

console.log() 는 window 객체에 있는 변수이므로 f1 함수 에 있다고 해도 전역 컨텍스트에서 실행된다.

렉시컬 스코프

자바스크립트가 이러한 자료구조를 가지는 것은 렉시컬 스코프를 따르기 때문이다.
렉시컬 스코프는 함수를 어디에 선언하였는지에 따라 상위 스코프가 무엇인지 결정된다.

따라서, myFunc 함수 은 전역 실행 컨텍스트에 add 함수 는 함수 실행 컨텍스트에 쌓이게 된다.


3. this가 가리키는 것

동적 바인딩(dynamic binding)

함수가 호출되는 상황은 4가지가 있다.

  • 함수 호촐: myfunc()
  • 메스드 호출: o.method()
  • 생성자 호출: function Person() {}
  • 간접 호출: call apply bind (function 객체의 메소드)
  • callback 함수의 호출: 보통 다른 함수의 인자로 보내지는 함수이다.

함수의 호출 환경에 따라 this는 동적으로 세팅된다. 이렇게 this가 환경에 따라 바뀌는 것은 동적 바인딩(dynamic binding)이라고 한다.
bind apply call 등으로 this가 가리키는 것을 조작할 수 있다.


4. 화살표 함수와 일반 함수의 this

화살표함수의 this

화살표 함수의 this는 호출된 함수를 둘러싼 실행 컨텍스트를 가리킨다.
화살표 함수의 this는 정해지면 바꿀 수 없다. (call apply bind 를 사용해도 바뀌지 않는다.)
따라서 this 값을 고정시켜야 할 때 좋다. EX) callback 함수

일반함수의 this

일반 함수의 this는 새롭게 생성된 실행 컨텍스트를 가리킨다.

const o = {
	method() {
    	console.log("constext : ", this) //o
        let f1 = function () {
        	console.log("[f1] this: ", this)
        }
        let f2 = () =>
        	console.log("[f2] this : ', this}
           f1() // global
           f2() // o
        },   
};
o.method()

5. 자바스크립트 Closure

함수는 일급객체이다. (일급 함수: first-class object)

일급 객체 (first-class object)는 프로그래밍 언어의 기본적 조작을 제한없이 사용할 수 있는 대상을 의미한다. 즉, 함수를 변수와 같이 사용할 수 있으며, 함수 역시 할당이 가능하다는 의미이다.

함수를 다른 객체와 구분짓는 특징을 호출할 수 있다는 것이다.

다음의 조건을 만족하면 일급 객체로 간주한다.

  • 무명의 리터럴로 표현이 가능하다.
  • 변수나 자료 구조(객체, 배열 등)에 저장할 수 있다.
  • 함수의 매개변수에 전달할 수 있다.
  • 반환값으로 사용할 수 있다.

함수가 일급객체이기 때문에 할 수 있는 것은?

고차함수(higher order function)을 만들 수 있다.
콜백함수(callback)를 사용할 수 있다.

변수에 함수 할당

const foo = function() {
   console.log("foobar");
}
// 변수를 사용해 호출
foo();

함수를 인자로 전달

function sayHello() {
   return "Hello, ";
}
function greeting(helloMessage, name) {
  console.log(helloMessage() + name);
}
// `sayHello`를 `greeting` 함수에 인자로 전달
greeting(sayHello, "JavaScript!");

클로저(Closure)

자바스크립트 클로저는 함수의 일급 객체 성질을 이용한다.

클로저는 반환된 내부함수가 자신이 선언됐을 때의 환경(Lexical everionment)인 스코프를 기억하여 자신이 선언됐을 때의 환경(스코프) 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수이다. 더 간단하게 말하면 클로저는 자신이 생성될 때의 환경(Lexical everionment)을 기억하는 함수이다.

실행 컨텍스트의 관점에 설명하면, 내부함수가 유효한 상태에서 외부함수가 종료하여 외부함수의 실행 컨텍스트가 반환되어도, 외부함수 실행 컨텍스트 내의 활성 객체(Activation object) (변수, 함수 선언 등의 정보를 가지고 있다)는 내부함수에 의해 참조되는 한 유효하여 내부함수가 스코프 체인을 통해 참조할 수 있는 것을 의미한다.

closure을 왜 사용하나?

클로저를 사용하는 이유는 상태를 안전하게 은닉하고 보존하기 위해서다.
즉, 다수의 개발자와 함께 일을 할 때 실수를 방지하고 더 탄탄한 ㅋㅗ드를 만들기위한 코드 패턴이다.

profile
개발자를 꿈꾸는 코린이!

0개의 댓글