본문 바로가기

Study/JavaScript

this

JavaScript에는 화살표 함수 표현식(arrow function expression)이라는 게 있다. 보통 화살표 함수라고 줄여 부르는데, 2015년에 발행된 ES6부터 도입된 기능이라고 한다.

 

화살표 함수를 단순히 익명 함수(anonymous function)라고 부르기는 어렵다. 화살표 함수에 이름이 없긴 하지만, JavaScript에는 전통적인(traditional) 익명 함수가 존재하기 때문이다. 바로 흔히 말하는 함수 표현식이다. fucntion 키워드로 시작하여 함수를 정의하는 게 아니라, 변수에 함수를 할당하는 방식으로 이루어지는 함수 정의 방식.

 

그러한 전통적인 익명 함수와 화살표 함수 사이의 가장 큰 차이라고 한다면 역시 this 키워드일 것이다.

 

this 키워드는 누더기 같은 존재다.

 

  1. 초기 자바스크립트에서는 this의 바인딩이 명시적이지 않을 때 전역 객체(브라우저에서는 window)를 참조하도록 설계되었다.
  2. ES3에서는 object 내부의 메서드를 호출하면 this는 해당 object를 바인딩하도록 되었다. 하지만 중첩된 일반 함수는 여전히 전역 객체를 바인딩한다.
  3. ES5에서는 this의 바인딩을 명시적으로 결정하는 바인딩 메서드(call(), bind(), apply())가 도입되었고, 의도에서 벗어나는 this 활용을 일부 막기 위해 strict mode가 도입되었다. strict mode에서는 일반 함수의 this에 undefined가 바인딩된다.
  4. ES6에서는 화살표 함수가 추가되었고, 클래스 문법이 도입되었다. 화살표 함수의 this는 화살표 함수를 둘러싸고 있는 가장 가까운 일반 함수 스코프 혹은 전역 객체를 가리킨다(즉, "상속" 받는다). 클래스의 인스턴스 내부에서의 this는 인스턴스를 가리키도록 바인딩된다.

 

이외에도 this의 바인딩은 달라질 수 있다. 이벤트 핸들러, 생성자, 콜백 함수. 그러니까 이렇게 말하는 것이 좋겠다.

 

this의 바인딩은 함수 호출 패턴(function invocation)의 종류에 따라 달라진다

 

 

 

그리고 각 케이스에 대해서 외우는 수밖에 없다.

 

이벤트 핸들러와 생성자, 클래스 인스턴스의 경우에는 명백하므로 따로 언급하지 않겠다. 다음은 그 외의 경우에 대해 이런저런 경우를 나열한 JavaScript 코드다.

 

 

var number = 0;

const obj1 = {
  number: 1,
  func0: function(num) {
    console.log(num);
  },
  func1: function(ob) {
    console.log(ob.number);
  }
};

const obj2 = {
  number: 2,
  func2: function() {
    obj1.func1(this);
  },
  func3: () => console.log(this.number),
  func4: function() {
    const number = 2.1;
    const innerFunc = () => {
      console.log(this.number);
    };
    innerFunc();
  },
  func5: function() {
    const number = 3;
    const innerFunc = function() {
      return this.number;
    };
    obj1.func0(innerFunc());
  },
  func6: function() {
    const number = 3;
    const innerFunc = () => console.log(this.number);
    innerFunc();
  },
  func7: function() {
    const number = 4;
    const innerFunc1 = function() {
      const number = 4.1;
      const innerFunc2 = function() {
        console.log(this.number);
      };
      innerFunc2();
    };
    innerFunc1();
  },
  func8: function() {
    const number = 5;
    const innerFunc1 = function() {
      const number = 5.1;
      const innerFunc2 = () => console.log(this.number);
      innerFunc2();
    };
    innerFunc1();
  },
  obj3: {
    number: 6,
    func9: function() {
      console.log(this.number);
    },
    func10: function() {
      const number = 7;
      const innerFunc = () => console.log(this.number);
      innerFunc();
    }
  }
};

console.log(this.number);
obj1.func1(this);
obj2.func2();
obj2.func3();
obj2.func4();
obj2.func5();
obj2.func6();
obj2.func7();
obj2.func8();
obj2.obj3.func9();
obj2.obj3.func10();

 

 

출력값을 예측해보는 건 재밌는 게임이 될 것이다.

'Study > JavaScript' 카테고리의 다른 글

클래스와 프로토타입  (0) 2024.06.12
[Vue.js] props  (0) 2024.05.08