[javascript] Execution Context, Hoist, Scope

dev stefanCho·2021년 11월 28일
0

javascript

목록 보기
16/26

code가 run할때 마다 Execution Context가 실행된다. (처음에는 global, call stack에 쌓임)

Execution Context


Global Execution Context

Global Execution Context에서는 아래 3가지가 생성됨

1. Global Object

var a = 'cho'
console.log(window.a) // 'cho'

2. this object

this === window // true

3. Hoisting

기본적으로 var과 function delcaration은 hoist 된다.

function expression도 hoist 되는가?
console.log('function expression: ', test) // function expression:  undefined
console.log('function expression invoke: ', test()) // Uncaught TypeError: test is not a function
var test = function() {
    console.log('test')
}
  • function expression은 그냥 값이기 때문에 undefined로 hoisting 된다.
같은 function declaration이 있는 경우는 어떤게 hoist 되는가?
function a() {
  console.log('hi');
}

a(); // bye가 출력된다. 

function a() {
  console.log('bye');
}
  • 실행순서에 따라서 마지막 a가 hoisting 되어 메모리에 들어있기 때문이다.
var, function은 되도록 피하자

예기치 않게 일어나는 Hoist는 코드해석을 어렵게 만든다. 따라서 const, let을 쓰도록 하자.
아래 예제코드로 어떤 상황이 발생하는지 비교할 수 있다.

Function Execution Context

Each Execution Context has each environment (Call Stack에 쌓이는 각각의 function들에는 각자의 EC가 있다.)
Function Execution Context에서는 추가로 arguments가 생성된다.

arguments

function test (p1, p2) {
    console.log(arguments);
}

test('hi', 'bye') // Arguments(2) ['hi', 'bye', callee: ƒ, Symbol(Symbol.iterator): ƒ]

arguments는 optimization에 bad effect이므로, 사용하지 않도록 한다.

Lexical


In javascript out lexical scope (available data + variables where the function was defined) determines our available variables. Not where the function is called (dynamic scope)

lexical은 compile할 때 결정된다. compiler와 interpreter가 봤을 때, code가 어디에 쓰여있는지(where is function written)에 따라서 결정되는 것


Scope


Scope Chain

function scope는 각자의 scope를 갖는다.
parent의 scope에도 접근할 수 있는데 이것을 scope chain이라고 한다.
이것이 모든 environment가 global variable에 접근할 수 있는 이유이다.

Global Environment와 scope chain된 경우

Reference from Udemy Course : Javascript: The Advanced Concepts
var x = 'x';
function findName() {
  var b = 'b';
  return printName();
}

function printName() {
  var c = 'c';
  return 'abc';
}

function sayMyName() {
  var a = 'a';
  return findName();
}

sayMyName();

Function Environment내에서 scope chain된 경우

Reference from Udemy Course : Javascript: The Advanced Concepts
function sayMyName() {
  var a = 'a';
  return function findName() {
    var b = 'b';
    console.log(c); // ReferenceError: c is not defined (c의 declaration이 없다는 뜻)
    return function printName() {
      var c = 'c';
      console.log(b); // b
      return 'abc';
    }
  }
}

sayMyName()()();

Chrome에서 [[Scope]] 확인하기

lexical Envrionment는 [[Scope]]로 표시된다.
크롬에서 확인해보자. (이미지 가장아래에 [[Scope]를 확인할 수 있다.)

function scope

  • function에 의해서 scope 범위가 정해짐
  • var은 block scope를 가질 수 없다.
// function scope for var
function a() {
	var test = 123;
}

console.log(test); // Uncaught ReferenceError: test is not defined

// block scope for var
if (4 > 1) {
	var test = 123;
}

console.log(test); // 123 , var은 block scope가 없음, 따라서 같은 레벨의 scope로 봄

block scope

  • let과 const는 block scope를 가질 수 있다.
  • for loop에서 let이나 const를 사용함
// block scope of if statement
if (4 > 1) {
	let test = 123;
}

console.log(test); // Uncaught ReferenceError: test is not defined


// block scope of for loop
function loop() {
  for (let i = 5; i < 5; i++) {
    console.log(i);
  }
  console.log('final : ', i); //  Uncaught ReferenceError: i is not defined
}

loop();
profile
Front-end Developer

0개의 댓글