Execution context

image.png
1) 어떤 함수가 호출되면, 실행 컨텍스트(execution context)가 만들어진다.

  • call stack에 push
  • 함수를 벗어나면 call stack에서 pop

2) scope 별로 생성
3) 여기에 담긴 것

  • scope 내 변수 및 함수 (Local, Global)
  • 전달 인자 (arguments)
  • 호출된 근원 (caller)
  • this

    'this' keyword

    1) 모든 함수 scope 내에서 자동으로 설정되는 특수한 식별자
    2) execution context의 구성 요소 중 하나로, 함수가 실행되는 동안 이용할 수 있다

👉 5 Patterns of Binding 'this'

  • Global : window

  • Function 호출 : window

    var name = 'Global Variable';
    
    // case1  
    console.log(this.name); // Global Variable
    
    // case2
    function foo() {
      console.log(this.name);
    }
    
    foo(); // Global Variable
    
    // case3
    function outer() {
      function inner() {
        console.log(this.name);
      }
    
      inner();
    }
    outer(); // Global Variable
  • Method 호출 : 부모 Object

    // case 1
    let counter = {
      val : 0,
      increment : function() {
        this.val ++;
      }
    }
    
    counter.increment();
    counter.val // 1
    
    // case 2
    let obj = {
      fn : function(a, b) {
        return this;
      }
    }
    let obj2 = {
      method : obj.fn
    }
    
    console.log(obj.fn() === obj) // true
    console.log(obj2.method() === obj2) // true
    // 함수를 실행시킨 대상이 this가 된다
  • Construction Mode
    (new 연산자로 생성된 function 영역의 this) : 새로 생성된 객체

    function Food(name) {
      this.name = name;
    }
    
    let food1 = new Food('지코바');
    
    food1.name // "지코바"
  • .call 또는 .apply 호출 : call, apply의 첫번째 인자로 명시된 객체

    // case1
    function identify() {
      return this.name.toUpperCase();
    }
    
    function speak() {
      let greeting = "Hello, I'm " + identify.call(this);
      console.log(greeting);
    }
    
    let me = {name : 'Heaeun'};
    let you = {name : 'Daeun'};
    
    identify.call(me); // "HEAEUN"
    identify.call(you); // "DAEUN"
    speak.call(me); // Hello, I'm HEAEUN
    speak.call(you); // Hello, I'm DAEUN

✔ 종합 예제 ✔

let fn = function (one, two) {
  console.log(this, one, two);
};

let r = {r:1};
let g = {g:1};
let b = {b:1};
let y = {y:1};

r.method = fn;

r.method(g, b); // this : r
fn(g, b); // this : window
fn.call(r, g, b) // this : r
r.method.call(y, g, b) // this : y