본문 바로가기

JavaScript/AboutJS

[JavaScript] This 를 판단하는 기준

 

이글은 실행 컨텍스트에서 넘어왔습니다.

https://daunje0.tistory.com/61

 

[JavaScript] 실행 컨텍스트 ( Execution Context )

Execution Context (실행 컨텍스트) 란? 자바스크립트의 실행 환경을 추상화한 개념으로, 코드(함수)가 실행되기 위해 필요한 환경 정보를 담고 있는 객체이다.  1. 구성 요소 Lexical Environment원래는

daunje0.tistory.com

 

 

 

앞서 살펴 본 것처럼 this binding 은 실행 컨텍스트가 실행될 때, 시작 되게 된다

 

 

 

실행 컨텍스트가 생성되는 때는 이 컨텍스트에 해당하는 함수가 호출되는 순간이다.

이 말은 this 도 함수가 호출될 때에 무엇을 지칭할 지 결정된다는 뜻이다.
java 처럼 정적으로 정해진 것이 아닌 동적으로 정해지기 때문에 항상 헷갈리는 게 
자바스크립트의 this 다.

 

호출하는 방식에 따라 달라지는 this 의 기준은 다음처럼 5가지로 나뉘어진다.

 

  1. 전역공간에서
  2. 함수 호출시
  3. 메서드 호출시
  4. callback 호출시
  5. 생성자 함수 호출  / 클래스에서 ( 앞으로 생성될 인스턴스 자체 )

 

1. 전역 공간에서의 this

 

전역공간에서는 무조건 처음부터 호출되기 때문에 항상 정해져 있다.

전역객체인 window / global 을 지칭한다

( 브라우저에서는 window, node.js 에서는 global ) 

개념상 전역 컨텍스트를 실행하는 주체가 전역 객체( host 객체 )이기 때문이다.

 

 

2. 함수 호출시 this

 

전역객체인 window / global 을 지칭한다 ( 단, strict mode 에선 undefined : 함수 스코프 안에 this 가 없으므로)

        function a() {
          console.log(this);
        }
        a();

전역공간에서 함수를 호출하는 순간에 실행하는 주체는 전역 객체가 된다.

 

하지만 아래와 같은 예는 머리를 갸우뚱하게 된다.

function b() { 
  function c() { 
    console.log(this)
  } 
  c();
}
b();

c를 호출했을 때는 b함수 안에 있기 때문에 호출한 주체는 b함수가 되어야 할 거 같은데 

로그는 전역 객체로 나오게 된다.

 

이게 버그라는 의견도 있고 아니라는  의견도 있다고 하는 데,

ES6에서는 아예 this 바인딩을 하지 않는 화살표 함수가 나오게 된다.

(화살표 함수는 바로 위 컨텍스트의 this 를 그대로 사용한다)

 

var d = {
  e: function () {
    function f() {
      console.log(this);
    }
    f()
  }
}
d.e()

f( ) 로 함수로써 호출했기 때문에 this 는 전역 객체가 된다.

 

 

3. 메서드 호출시 this

 

자바스크립트에서 메서드의 개념


1. 객체의 속성으로 정의된 함수
2. 클래스 내부에 정의된 함수
3. 프로토타입에 추가된 함수

 

여기서는 객체의 속성으로 정의된 함수를 호출할 때의 this 를 알아보자.

 

여기서의 this 는 메서드 호출 주체( 메서드 명 앞)

메서드 명의 ' 점 ' 바로 앞의 대상이 this 가 된다.

 

예 1)

이런 식으로 a.b() 를 호출하게 되면

this는 a 가 된다.

b 함수를 a 객체의 메서드 로서 호출을 했기 때문이다.

 


예 2)

 

여기서의 this 는 b객체가 된다.

 


참고: 메서드 내부함수에서의 this 우회법 (원하는 스코프를 this 에 담기) https://daunje0.tistory.com/manage/newpost/50

 

Tistory

좀 아는 블로거들의 유용한 이야기

www.tistory.com

 

 

4. 콜백 함수에서의 this

기본적으로는 함수의 this 와 같다

제어권을 가진 함수( 예 : setTimeout ) 가 콜백의 this를 지정해둔 경우도 있다.

 - 이 경우에도 개발자가 this 를 바이딩해서 콜백을 넘기면 그에 따른다.

 

예 1-1)

var callback = function () {
    console.dir(this) // 출력 : Window
  }
var obj = {
  a: 1,   
  b: function (cb) {
  cb() // 함수로써 호출
  }
}
obj.b(callback)

 

 

예 1-2)

var callback = function () {
    console.dir(this) // 출력 obj 객체
  }
  var obj = {
    a: 1,
    b: function (cb) {
      cb.call(this) // obj 객체를 this 로 넘김
    }
  }
  obj.b(callback)

 

 

예 1-1) 출력 결과

 

위 결과에서 확인한 것 처럼, callBack 함수을 호출한 방식에 따라 결과값이 바뀐다.

예 2-1)

  var callback = function () {
    console.dir(this) // 0.1초 후, 출력: window
  }
  var obj = {
    a: 1
  }
  setTimeout(callback, 100);

 

예 2-2)

  var callback = function () {
    console.dir(this) // 0.1초 후, 출력: obj
  }
  var obj = {
    a: 1
  }
  setTimeout(callback.bind(obj), 100);

예 2-2) 출력 결과

 

5. 생성자 함수 호출시

새로 만들 인스턴스 객체가 this

  function Person(n, a) {
    this.name = n
    this.age = a
  }
  var tom = Person('tom', 20)
  console.log(window.name, window.age); // 출력 tom 20


  function Person(n, a) {
    this.name = n
    this.age = a
  }
  var tom = new Person('tom', 20)
  console.log(tom);

 

 

 

정재남 님의 코어 자바스크립트 강의를 바탕으로 정리한 내용입니다

 

관련 내용
https://daunje0.tistory.com/90

 

[JavaScript] Closure (클로져)

클로저(Closure)는 1. 내부 함수와2. 그 함수가 선언될 때의 렉시컬 환경(Lexical Environment)의 조합 이다. 1. 내부 함수: 다른 함수 내부에 정의된 함수2. 렉시컬 환경: 함수가 선언될 때 생성되는 환경

daunje0.tistory.com