본문 바로가기
javascript

Execute context

by rami_ 2022. 2. 2.

실행컨텍스트 execute context실행할 코드에 제공할 환경 정보를 모아놓은 객체로, 자바스크립트의 동적 언어로서의 성격을 가장 잘 파악할 수 있는 개념. 어떤 실행컨텍스트가 활성화되는 시점에 선언된 변수를 위로 끌어올리고(hoisting), 외부환경 정보를 구성하고 this값을 설정하는 등의 동작을 수행.

 

*스택stack : 출입구가 하나뿐인 깊은 우물 같은 데이터 구조

*큐 queue : 양쪽이 모두 열려 있는 파이프. 종류에 따라 양쪽 모두 입력과 출력이 가능한 큐도 있으나 보통은 한쪽은 입력만, 다른한쪽은 출력만을 담당하는 구조

 

어디서나 Global에 접근할 수 있고 n0 = n0라고 하면 window객체에 저장됨

 

아무것도 사용하지 않거나 var를 사용하면 global scope에 저장됨(함수안에서 var를 사용하면 local scope로 들어옴). let, const는 script scope에 저장됨(함수안에서는 local scope로 들어감). 그렇기 때문에 let과 const 변수에 할당된 것들은 window. 으로 불러내면 나오지 않음(undefined가 나옴)

 

callstack에 execute context가 쌓임

(anonymous) <-최초로 생기는 excute context이며 Global excute context라고 부름.

함수가 쌓이게 되면 function excute context라고 부름.

 

Global Execute Context에서 실행될 때

a=1 Global
var a =1 Global
let a =1 Script
const a =1 Script

Function Execute Context에서 실행될때

a=1 Global
var a =1 Local
let a =1 Local
const a =1 Local

 

var는 hoisitng되면 초기화됨.

let, const는 초기화가 되지 않음. 선언하기 전에 접근할 수 없음. "temporal dead zone(시간적 데드존)" 변수가 선언하기 전에 액세스 하려고 하면 ReferenceError가 발생함.

fucnction () {
  console.log(name);
  console.log(name2);
  var name = "rami"; //여기서는 var, let 모두 local scope
  let name2 = "ramimimi";
  }
  
  //hoisitng
  
fucnction () {
  var name;
  let name2; 
  console.log(name); //undefined
  console.log(name2); //ReferneceError
  name = "rami";
  name2 = "ramimimi";
  }

 

 

 

VariableEnvironment : 현재 컨텍스트 내의 식별자들에 대한 정보 + 외부 환경 정보, 선언 시점의 LexicalEnvironment의 스냅샷으로 변경사항은 반영되지 않음. environmentRecord(snapshot), outerEnviornmentReferences(snapshot)

LexicalEnvironment : 처음에는 VariableEnvironment와 같지만 변경사항이 실시간으로 반영됨. environmentRecord, outerEnviornmentReferences

ThisBinding : this식별자가 바라봐야할 대상 객체

 

실행컨텍스트를 생성할 때 VariableEnvironment에 정보를 먼저 담은 다음, 이를 그대로 LexicalEnvironment를 만들고, 이후에는 LexicalEnvironment를 주로 활용하게 됨.

 

environmentRecord : 현재 컨텍스트와 관련된 코드의 식별자 정보들이 저장됨. 컨텍스트를 구성하는 함수에 지정된 매개변수 식별자, 선언한 함수가 있을 경우 그 함수 자체, var로 선언된 변수의 식별자 등이 식별자에 해당함. 컨텍스트 내부 전체를 처음부터 끝까지 쭉 훑어나가며 순서대로 수집함.

 Hoisting : 자바스크립트 엔진은 식별자들을 최상단으로 끌어올려놓은 다음 실제 코드를 실행함. 자바스크립트 엔진이 실제로 끌어올리지는 않지만 편의상 끌어올린것으로 간주.

 

function a (x) {
  console.log(x); //1)
  var x;
  console.log(x); //2)
  var x = 2;
  console.log(x); //3)
}
a(1)
//////////////매개변수를 선언/할당과 같다고 간주해 변환함.
function a (1) {
  var x =1; //1을 매개변수로 넣음.
  console.log(x);
  var x;
  console.log(x);
  var x = 2;
  console.log(x);
}
a()
//////////hoisting
function a () {
  var x;
  var x;
  var x;
  
  var x =1; 
  console.log(x);
  console.log(x);
  var x = 2;
  console.log(x);
}
a(1)
function a () {
  console.log(b); // 1)
  var b = 'bbb';
  console.log(b); // 2)
  function b () { } 
  console.log(b); // 3)
}
a();

//////////hoisting
function a () {
  var b;
  function b() {}
  
  console.log(b); // 1)
  b = 'bbb';
  console.log(b); // 2) 
  console.log(b); // 3)
}
a();

//////hoisting이 끝난 상태에서의 함수선언문은 함수명으로 선언한 변수에 함수를 할당한 것처럼 여길 수 있음
function a () {
  var b;
  var b = function b() {}
  
  console.log(b); // 1) function b () {}
  b = 'bbb';
  console.log(b); // 2) bbb
  console.log(b); // 3) bbb
}
a();

 

함수선언문과 표현식

함수선언문 function declaration : function 정의부만 존재하고 별도의 할당 명령이 없음.

함수표현식 function expression : 정의한 function을 별도의 변수에 할당하는 것

function a () {/* ... */} //함수선언식
a(); //실행

var b = function () {/* ... */} //(익명)함수표현식. 변수명이 곧 함수명
b(); //실행

var c = function d () {/*...*/} //기명함수표현식 변수명은 c, 함수명은 d
c(); //실행
d(); //실행X 함수내부에서 재귀함수를 호출하는 용도로 쓸 수 있음.
console.log(sum(1,2));
console.log(multiply(3,4));

function sum (a, b) {
  return a + b;
}

var multiply = function (a, b) {
  return a * b;
}
//////hoisting
var sum = function sum (a, b) { //함수선언문은 전체를 끌어올림
  return a + b;
}
var multiply; //함수표현식은 변수만 hoisting됨

console.log(sum(1,2)); //3
console.log(multiply(3,4)); //mutiply is not a function


multiply = function (a, b) {
  return a * b;
}

코드를 실행하는 중에 실제로 호출되는 함수는 오직 마지막에 할당한 함수, 즉 맨 마지막에 선언된 함수.

함수 선언식보다는 함수 표현식으로 정의하는 것이 좋음.

 

Scope : 식별자에 대한 유효 범위

Scope Chain : 식별자에 대한 유효범위를 안에서 바깥으로 차례로 검색해 나가는것. 이걸 가능케 하는 것은 outerEnvironmentReference 

outerEnvironmentReference : 현재 호출된 함수가 선언될 당시의 LexicalEnvironment를 참조함. LinkedList의 형태를 띔(A 함수 내부에 B함수를 선언하고 다시 B함수 내부에 C함수를 선언한 경우, 함수 C의 outerEnvironmentReference는 함수 B의 LexicalEnvironment에 있는 outerEnvironmentReference는 다시 함수가 선언되던 때(A)의 LexicalEnvironment를 참조)

여러 스코프에서 동일한 식별자를 선언한 경우에는 무조건 스코프체인상에서 가장먼저 발견된 식별자에게 접근가능.

변수은닉화 variable shadowing : 함수내부에서 a를 선언한 경우 전역공간(global scope)에서 선언한 동일한 이름의 a 변수에는 접근할 수 없음. //함수 내부에서 a를 찾았기 때문에 더이상 나와서 찾지 않음.

전역변수 Global variable : 전역스코프에서 선언한 a와 outer 둘. 전역공간에서 선언한 변수

지역변수 Local variable : outer 함수 내부에서 선언한 inner와 inner함수 내부에서 선언한 a. 함수 내부에서 선언한 변수

가급적 전역변수 사용을 최소화하는 것이 좋음.

 

 

출처: 생활코딩 / 코어자바스크립트

'javascript' 카테고리의 다른 글

prototype/__proto__  (0) 2022.02.05
closure  (0) 2022.02.02
callback  (0) 2022.02.01
While  (0) 2022.01.25
자료구조 Data Structure  (0) 2022.01.24