This 키워드

Written on April 17, 2019

자바스크립트의 정말 헷갈리는 개념이자 정말 중요한 개념 중 하나인 This 키워드!

한마디로 This를 정의하자면,

This는 호출 시점에서 실행함수가 가르키는 객체이다. 다른말로는 실행함수의 호출자. 라고 할 수 있을 것 같다.

자바스크립트에는 4가지 Pattern이 있는데, 일반함수 실행, 메소드 실행, 생성자 (new) 실행, 명시적 지정(call, apply, bind ) 이 그것이다.

일반함수 실행

함수실행에서의 This는 전역객체(window)이다.

function add(x, y) {
  console.log(this);
  return x + y;
}
add(3, 4);
// window -> add()에서 this는 전역객체(window)
// 7

그렇다면, 아래 코드를 실행한 후 result 값은 무엇이 될까?

var x = 10;
var add = function(y) {
  var x = 20;
  return this.x + y;
};
result = add(10); // 20

add() 함수 내에서 새로 선언된 x=20; 때문에 답이 30이라고 생각할 수 있지만, 실행시점에서 this는 window이다. 또한, 자바스크립트에서 변수는 함수 스코프를 가지므로, 함수 실행시점에서 x는 전역에서 선언된 10이되고, result = 20이다. (add 함수 내에 console.log(x); 를 하면, 20이 찍힐 것이다.)

메소드 실행

메소드란, 객체의 속성으로 정의된 함수이다. 이 경우, This는 해당 메소드를 소유하고 있는 객체가 된다.

var obj = {
  foo: function() {
    console.log(this);
  }
};
// obj

생성자(new) 실행

생성자는 new 로 객체를 만드는 것이고, 이 때, this는 new를 통해 만들어 진 새로운 변수이다.

function Human(name, hobby) {
  this.name = name;
  this.hobby = hobby;
  this.newThis = function() {
    return this;
  };
}
const aHuman = new Human("Steve", "Swimming"); //new로 Human 객체 생성
aHuman.newThis(); // Human

명시적 지정

.call()이나, .apply(), .bind()를 이용하여 This를 명시적으로 지정해줄 수 있다. .bind()는 이후 새 포스팅을 통해 소개하도록 하고, 이번엔 .call()과 .apply()만 다루고자 한다. .call()과 .apply()의 역할은 동일하나, .apply()는 배열/유사배열을 인자로 받는다는 것이 다르다.

func.call(thisArg, arg1, arg2…) / func.apply(thisArg, [arg1, arg2…])

여기서 thisArg 자리에 명시적으로 지정해줄 This 객체를 적으면 된다. 이 때의 This는 명시적으로 지정해준 This이다.

var obj1 = {
  foo: function() {
    console.log(this);
  }
};
var obj2 = {
  foo: obj1.foo
};
obj1.foo.call(obj2); // obj2

obj1의 foo 함수를 실행하지만, call을 이용하여, this가 obj2 임을 지정해 주었기 때문에 this는 obj2이다.

코딩을 하다보면 This의 늪에 빠지게 되어, 범인은 또 This야!! 라고 울컥울컥 하기도 하지만, 자바스크립트의 유연성을 대표하는 매력적인 키워드 인것 같다. 😛

👩🏻‍💻 배우는 것을 즐기는 프론트엔드 개발자 입니다
부족한 블로그에 방문해 주셔서 감사합니다 🙇🏻‍♀️

in the process of becoming the best version of myself