[Part4] 함수와 실행컨텍스트

누리·2023년 8월 14일
0

Interview

목록 보기
9/13

물어보는 이유?

JavaScript의 핵심적인 개념에 대해 얼마나 깊이 이해하고 있는지,
그리고 이러한 이해를 바탕으로 복잡한 문제를 해결할 수 있는 능력이 있는지 평가하려는 것입니다.

  • 함수 이해 : JavaScript는 일급 함수를 지원하는 언어입니다. 이는 함수를 변수에 할당할 수 있으며, 다른 함수의 매개변수로 전달하거나, 함수에서 반환할 수 있다는 것을 의미합니다. 또한, JavaScript의 함수는 클로저를 생성하며, 이는 함수가 정의된 시점의 변수에 접근할 수 있도록 합니다. 함수에 대한 깊은 이해는 이러한 고급 개념을 이해하고 사용하는데 필수 적입니다.
  • 실행 컨텍스트 이해 : 실행 컨텍스트는 JavaScript 코드가 평가되고 실행되는 환경을 의미합니다. 각 함수 호출마다 새로운 실행 컨텍스트가 생성되며, 이는 변수, 함수 선언, this, 외부 환경에 대한 정보를 포함합니다. 실행 컨텍스트는 스택에 쌓이고, 함수 실행이 완료되면 스택에서 제거됩니다. 실행 컨텍스트에 대한 이해는 스코프 체인, 클로저, 호이스팅 등 JavaScript의 중요한 동작을 이해하는 데 필수적입니다.

주요 키워드 정리

  1. 함수 (Function) : JavaScript에서 함수는 일련의 문장들을 그룹화하는 기본적인 코드 블록입니다. 이것은 재사용 가능하고, 코드의 모듈화를 돕습니다.

//함수 (기명함수)
function add(num1, num2) {
  return num1 + num2;
}

//함수를 변수에 할당한 것 (익명함수)
const add2 = (num1, num2) {
  return num1 + num2;
}

const add3 = function (num1, num2) {
  return num1 + num2;
}

add(2, 3); //5
add2(2, 3); //5
add3(2, 3); //5

const someFn = (callback) => {
  const someValue = callback();
  
  returen somValue;
}
  1. 함수 선언(Function Declaration)과 함수 표현식(Function Expression) : JavaScript에서 함수는 선언적 형식과 표현식 형식으로 정의될 수 있습니다. 이들 간의 차이점과 언제 어떤 것을 사용해야 하는지에 대해 이해해야 합니다.

  2. 익명함수(Annonymous Function)와 기명 함수(Named Function) : JavaScript에서 함수는 이름이 있거나 없을 수 있습니다. 이들 간의 차이점과 언제 어떤 것을 사용해야 하는지에 대해 이해해야 합니다.

  3. 실행 컨텍스트(Execution Context) : JavaScript의 실행 컨텍스트는 실행 가능한 코드에 제공할 환경 정보들을 모아놓은 객체로, 자바스크립트의 동적 언어로서의 성격을 가장 잘 파악할 수 있는 개념입니다. 이것은 변수, 함수 선언, 스코프, this 키워드 등을 관리합니다.

  4. 변수 환경(Variable Environment)와 활성 객체(Active Object) : 이들은 실행 컨텍스트 내부에 존재하며, 변수와 함수 선언을 담당합니다.

  5. 호이스팅(Hoisting) : JavaScript에서 변수와 함수 선언이 그들의 포함된 스코프의 상단으로 끌어올려지는 동작을 의미합니다. 이것이 어떻게 작동하는지에 대해 이해해야 합니다.

  6. 클로저(Closure) : 클로저는 JavaScript의 함수 실행 컨텍스트, 그리고 스코프 체인과 밀접한 관련이 있습니다. 클로저는 함수가 선언된 시점의 환경을 기억하는 JavaScript의 중요한 특징입니다.

  7. this 키워드 : JavaScript의 this 키워드는 함수가 실행되는 컨텍스트를 참조합니다. this는 다른 프로그래밍 언어와 달리, JavaScript에서는 함수가 호출되는 방식에 따라 결정됩니다.

  8. 스코프(Scope)와 스코프 체인(Scope Chain): 스코프는 변수와 함수의 접근성과 생명 주기를 결정합니다. 스코프 체인은 변수의 검색을 위한 메커니즘입니다.

  9. 전역 컨텍스트(Global Context): JavaScript 코드가 시작 실행될 때, JavaScript 엔진은 전역 실행 컨텍스트를 생성합니다. 전역 컨텍스트는 코드가 실행되는 동안 유지되며, 전역 변수와 전역 함수를 포함합니다.

  10. 함수 컨텍스트(Function Context): 함수가 호출될 때마다, JavaScript 엔진은 해당 함수를 위한 새로운 실행 컨텍스트를 생성합니다. 이 컨텍스트는 함수의 매개변수, 내부 변수 및 함수 선언에 대한 정보를 포함합니다.

  11. 실행 컨텍스트 스택(Execution Context Stack): 실행 컨텍스트는 실행 컨텍스트 스택 (또는 호출 스택)에 푸시되고 팝되는 방식으로 관리됩니다. 현재 실행 중인 컨텍스트는 항상 스택의 맨 위에 있습니다.

  12. 렉시컬 환경(Lexical Environment): 렉시컬 환경은 식별자 변수를 위한 환경 레코드와 외부 환경에 대한 참조를 포함하는 구조입니다. 실행 컨텍스트는 렉시컬 환경을 이용해 변수와 함수를 관리합니다.

  13. 블록 스코프(Block Scope): let과 const 키워드를 사용해 선언된 변수는 블록 스코프를 가집니다. 이는 해당 변수가 선언된 블록 내에서만 접근 가능하다는 것을 의미합니다.

  14. 함수 호이스팅(Function Hoisting)과 변수 호이스팅(Variable Hoisting): 함수 선언은 함수 호이스팅이 발생하며, var 키워드로 선언된 변수는 변수 호이스팅이 발생합니다. 그러나 let과 const 키워드로 선언된 변수는 호이스팅이 발생하지 않습니다.

  15. 즉시 실행 함수 표현식(IIFE, Immediately Invoked Function Expression): IIFE는 선언과 동시에 실행되는 JavaScript 함수입니다. 이것은 변수 충돌을 피하고 코드를 모듈화하는 데 유용합니다.

const { log } = console;
const sayHello = () => {
  log('안녕하세요');
}

sayHello(); // '안녕하세요'

//즉시 실행함수
(() => {
  log('안녕하세요')
})(); // '안녕하세요'

실행 컨텍스트, 스코프 체인 & 자바스크립트 내부

🧐 CallStack (Execution Context Stack)에 대해 더 깊게 파보자. primitive한 값들은 콜스택에 쌓인다고 했는데 도대체 어디에 쌓이는지 어떤식으로 실행할 코드에 제공할 환경 정보들을 모아놓는지 자세히 알아보자

📖 실행 컨텍스트는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체로, 자바스크립트의 동적 언어로서의 성격을 가장 잘 파악할 수 있는 개념입니다. (...) 실행 컨텍스트는 자바스크립트에서 가장 중요한 핵심 개념 중 하나입니다. 사실 클로저를 지원하는 대부분의 언어에서 이와 유사하거나 동일한 개념이 적용되어 있습니다. 실행 컨텍스트를 정확히 이해하는 것은 자바스크립트 뿐 아니라 일반적인 개발자로서의 실력 향상에도 큰 도움이 될 것입니다.
장재남, <코어 자바스크립트>

🔑 키워드

실행 컨텍스트 (Execution Context)

  • 코드의 실행 환경을 말한다.
  • JavaScript 코드가 실행될 때, JavaScript 엔진은 실행 컨텍스트를 만들고, 실행 컨텍스트 스택에 쌓아서 코드를 관리한다.

실행 컨텍스트 스택 (Execution Context Stack)

  • 생성된 실행 컨텍스트를 관리하는 구조이다.
  • 현재 실행 중인 컨텍스트는 항상 스택의 맨 위에 있다.

렉시컬 환경 (Lexical Environment)

  • 식별자(변수명)-값 쌍을 포함하는 구조로, 실행 컨텍스트를 통해 변수와 함수를 관리한다.

실행 컨텍스트 (EC :: Execution Context)

💡 실행 컨텍스트(EC)는 JavaScript 코드가 실행되는 환경으로 정의되고, 실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다.
여기서 환경이란? JavaScript 코드가 특정 시간에 엑세스 할 수 있는 this, 변수, 객체, 함수의 값을 의미한다.

var outer = function () {
  var count = 1;
  var inner = function () {
    return ++count;
  };
  return inner;
}
var outer2 = outer();

console.log(outer2); //inner 함수 반환
console.log(outer2()); //inner() 인데 inner함수는 가로막혀있다 클로저에 의해 count 값 업데이트 됨

Environment Record 와 호이스팅 (hoisting)

💡 Lexical Environment 안에 있는 Record 와 Outer Environment 를 가지고 호이스팅과 스코프를 알아보자

  • 호이스팅 ? 선언문이 마치 최상단에 끌어올려진 듯한 현상
  • Environment Record ? 식별자와 식별자에 바인딩된 값을 기록

Execution Context 생성단계에서 벌어지는 일

JS 엔진이 우리의 스크립트를 받게 되면, 첫 번째 일은 우리 코드의 데이터를 위한 메모리 설정입니다. 이 시점에서 코드는 실행되지 않으며, 단순히 실행을 위한 모든 것을 준비하는 것 뿐입니다. 함수 선언과 변수가 저장되는 방식은 다릅니다. 함수는 전체 함수에 대한 참조와 함께 저장됩니다(함수 호이스팅).

여기선 선언문만 실행해서 Record에 기록 하는 일을 하고,
함수일 경우 함수 호이스팅을 하고
var, const, let 키워드로 만들어진 변수일 경우 변수 호이스팅을 합니다.

console.log(name);
var name = 'nuri';

console.log(name2);
let name2 = 'nuri2';

// Environment Record
{
  name: undefined,
  name2: <uninitialized> // let으로 선언된 변수는 undefined로 초기화 되지 않음 >> 레퍼런스 에러가 뜸
}

함수 호이스팅과 변수 호이스팅 차이점?
차이점은 생성단계시점에서 value의 담을 때 어떤 값을 담느냐 입니다

  • 함수 호이스팅 :: 함수식별자, 함수를 모두 기록합니다.
  • 변수 호이스팅 :: 변수식별자를 담고 값은 undefined로 초기화 합니다.

Execution Context 실행단계에서 벌어지는 일

선언문 외의 나머지 코드를 순차적으로 실행합니다.
이 때는 Environment Record를 참조하거나 업데이트할 사항이 있다면 업데이트 합니다.

console.log(sum(2, 3));
console.log(city);
console.log(name);

function sum(x, y) {
  return x+y;
}
const name = "nuri";
let info = {
  age: 21,
  nationality: "Korea"
}
var city = "Seoul";

// Environment Record (Execution Context 생성단계)
{
  sum : <function>,
  name : <uninitialized>,
  info : <uninitialized>,
  city : undefined
}
// (실행 후)
{
  sum : <function>,
  name : "nuri",
  info : <Object>,
  city : "Seoul"
}

OuterEnvironment 와 스코프 (Scope)

  • 스코프 ? 변수나 함수에 접근할 수 있는 범위
  • OuterEnvironment reference ? 특정 컨텍스트에서 되부로 연결된 참조
    특정컨텍스트에서 어떤 변수나 함수에 접근할 수 있는지를 결정하는 스코프 체인의 일부입니다.
    예를들어, 내부 함수에서 외부 함수의 변수를 참조하려고 하면 JavaScript 엔진은 OuterEnvironment를 사용하여 외부 함수의 Environment Record를 찾습니다. 이를 통해 내부 함수는 외부 함수의 변수에 접근할 수 있습니다.
const name = "nuri";
const age = 21;
const city = "Seoul";

function getPersonInfo {
  const name = "Sori";
  const age = 24;
  return `${name} is ${age} and lives in ${city}`;
}
console.log(getPersonInfo()); // Sori is 24 and lives in Seoul

//Global Execution Context
{
  name: "nuri",
  age: 21,
  city: "Seoul"
}
//Local Executioin Context 
{
  name: "Sori",
  age: 24
  //city가 function 내에 존재하지 않기 때문에 외부에서 찾게 된다. (스코프체이닝)
}
const name = "sol";
const age = 20;
const city = "Seoul";

function getPersonInfo (name, age){
  return `${name} is ${age} and lives in ${city}`;
}

console.log(getPersonInfo('Sihyun', 25)); //Sihyun is 25 and lives in Seoul
profile
프론트엔드 개발자

0개의 댓글