티스토리 뷰

320x100

이 글은 주니어 개발자가 쓴 글로 오류가 있을 수 있습니다.
문제가 있거나 수정이 필요한 부분은 댓글로 알려주시면 감사하겠습니다.

 

2021년 1월 15일에 Velog에 작성한 글을 옮겨온 글입니다.


JavaScript의 this 키워드는 상황에 따라 다른 값을 참조하기도 하고, Java나 Python과 같은 다른 프로그래밍 언어와 다르게 동작하여 혼란을 야기할 때가 있습니다. JavaScript에서의 this는 무엇이고, 어떻게 동작하는지 알아보겠습니다.

this란?

this는 해당 키워드가 속한 개체를 참조합니다. JavaScript 엔진은 실행 중인 실행 컨텍스트의 LexicalEnvironment을 사용해 this 바인딩을 결정하는데요. 실행 컨텍스트는 함수를 호출할 때 생성되므로, 다시 말해 this는 함수를 호출할 때 결정됩니다.

호출 환경/방법에 따른 4가지 this 바인딩

  1. 전역 환경에서의 this - 전역 객체global object
    • browser 환경 - window 객체
    • node 환경 - global 객체
  2. 함수로서 호출한 경우
    • non-strict mode - 전역 객체global object
    • strict mode - undefined
  3. 메서드로서 호출한 경우 - 메서드를 호출한 객체
  4. 생성자 함수로서 호출한 경우, Class 내부에서의 this - 생성될(된) 인스턴스 객체
function testThisBinding () {
  console.log(this);
}
const obj = { testThisBinding };

console.log(this); // 1. window 객체
testThisBinding(); // 2. window 객체
obj.testThisBinding(); // 3. obj 객체
new testThisBinding(); // 4. testThisBinding {}
// strict mode
"use strict"
function testThisBinding () {
  console.log(this);
}

testThisBinding(); // 2. undefined
// class 내부의 this는 인스턴스 객체
class Person {
  constructor (name) {
    this.name = name;
  }
  testThisBinding () {
    console.log(this);
  }
}

const choi = new Person('Choi');
choi.testThisBinding(); // 4. Person { name: 'choi' }

명시적 this 바인딩

Function.prototype 메서드인 call, apply, bind 메서드로 명시적으로 this를 바인딩할 수 있습니다.

  1. call, apply 메서드
    this를 바인딩하고 인수와 함께 함수를 호출합니다.
    func.call(thisArg[, arg1[, arg2[, ...]]])
    func.apply(thisArg, [argsArray])​
  2. bind 메서드
    this와 인수를 바인딩한 새로운 함수를 생성합니다.
    bind된 함수는 name 프로퍼티가 bound xxx(xxx는 원본 함수의 이름)로 표시되므로 bind 여부와 원본 함수를 쉽게 알 수 있습니다.
    func.bind(thisArg[, arg1[, arg2[, ...]]])​

예외

화살표 함수(ES6)

화살표 함수는 this가 없으며, 화살표 함수 내부의 this는 렉시컬 스코프 상 가장 가까운 this를 반환합니다.

cf) 렉시컬 스코프: 함수를 선언하는 시점에 결정되는 스코프. 즉, 함수를 선언한 위치에 따라 스코프가 결정됨.

const obj = {
  outer: function () {
    console.log('outer: ', this); // outer: obj 객체
    const inner = () => {
      console.log('inner: ', this); // inner: obj 객체
    }
    inner();
  }
}

obj.outer();

콜백 함수

콜백 함수에서의 this는 콜백 함수의 호출 제어권을 갖는 함수에 의해 결정됩니다.

// 별도로 this를 바인딩하지 않는 경우
setTimeout(function () { console.log(this); }); // window 객체

// option으로 thisArg를 받는 경우
[1, 2, 3].forEach(function () { console.log(this); }, {}); // {}

// 메서드의 this를 상속하는 경우
document.body.querySelector('#root').addEventListener('click', function() {
  console.log(this);
}); // <div id="root">...</div>

참고 자료

320x100
댓글