본문 바로가기
Javascript

this 키워드 (this keyword in JavaScript)

by ttum 2020. 3. 23.

최근 자바스크립트에 대해 공부하며 이해한 내용을 바탕으로 작성한 것이며, 계속해서 새로 알게되는 내용이 있다면 추가할 예정입니다.

(* "use strict"모드에서는 다른 방식으로 동작하며 이를 사용하지 않는 경우를 가정하고 글을 작성했음을 밝힙니다.)

 

this란 무엇일까?

Mozilla MDN사이트에 의하면 this는 다음과 같다.

In most cases, the value of this is determined by how a function is called (runtime binding).

함수가 어떻게 불리는지에 따라서 this의 값이 결정된다고 한다. 

 

this 키워드는 해당 함수를 호출하는 객체를 가리키기 위해 사용된다.

함수를 호출하는 객체? 무슨 말일까?

 

아래의 코드를 살펴보자.

var person = {
  name: 'Peter',
  introduce(){
    return `My name is ${this.name}.`
  }
}

console.log(person.introduce()); // My name is Peter.

introduce() 함수를 호출하는 주체는 무엇인가? 바로 .(쩜) 앞에있는 person이다.

따라서 위 코드에서 this는 person 객체를 나타낸다. (this == 함수 호출 주체)

 

그렇다면 아래의 코드에서 introduce() 함수를 호출하는 주체는 무엇일까?

var name = "Peter";

function introduce () {
  return `My name is ${this.name}.`
}

console.log(introduce());

브라우저에서 global object인 window 객체가 바로 introduce()함수를 호출하는 주체이다.

이 글에서는 window객체에 대해 많이 다루지 않을 것이기 때문에 결론만 말하자면, Global 실행 컨텍스트이기 때문에 window.introduce()를 줄여 표현한 것이라고 생각하면 된다.  (따라서 this.introduce()window.introduce(), introduce() 모두 같은 결과가 나온다.)

따라서 이 코드에서 this는 introduce() 함수의 실행 주체인 window 객체가 된다.

* var 변수를 쓸 때를 말하며 const나 let은 변수를 할당해도 Global Object인 window객체에 추가되지 않으며 

this는 왜 쓰는 것일까?

이제 this에 대해 어렴풋이 이해가 되었을 것이다. this는 자신을 호출하는 객체를 가리킨다.

this를 쓰는 이유는 두가지 정도로 추려볼 수 있다.

1. 함수가 자기 자신의 객체에 접근할 수 있게 한다. (위에서 다룬 내용이다.)

2. 다양한 객체를 하나의 코드로 접근할 수 있게 한다.

 

다양한 객체에 접근이란 것이 무슨 말일까? 코드를 통해 살펴보자.

아래 코드의 결과는 어떻게 될까?

function introduce () {
  return `My name is ${this.name}.`
}

obj1 = { 
  name: "Peter",
  introduce: introduce
}
obj2 = { 
  name: "Sunny",
  introduce: introduce  
}

console.log(obj1.introduce())
console.log(obj2.introduce())

첫번째 로그에서 함수 실행의 주체는 obj1이다. 따라서 introduce 안의 this는 obj1을 가리킨다.

두번째 로그에서 함수 실행의 주체는 obj2이다. 따라서 introcude 안의 this는 obj2를 가라킨다.

이 결과에 대해서는 아마 쉽게 이해했을 것이다.

 

this라는 키워드를 사용함으로서 introduce라는 함수를 재사용할 수 있었다. 위처럼 this는 다양한 이유로 사용이 된다.

 

조금 더 어려운 예제!

다음 코드의 결과는 어떻게 될까?

var a = function(){
  console.log('a', this);
  var b = function(){
    console.log('b', this);
    var c = {
      hi: function(){
        console.log(this)
      }
    }
    c.hi();
  }
  b();
}
a();

결과는 다음과 같다.

함수 a에서 출력한 this가 window객체라는 것에는 당연히 동의를 할 것이다.

(a()를 호출한 대상은 Global object인 window 객체일 것이고, window.a()도 같은 결과를 냈을 것이므로! )

b를 호출한 경우에는 얼핏보면 a 안에서 호출이 되었기 때문에 헷갈릴 수 있다. 하지만, b의 호출주체 (xx.b())라고 가정했을때 xx를 따로 명시해주지 않았으므로 마찬자기로 window가 되는 것이다.

c는 hi라는 함수 앞에 "c."이 붙어있기때문에 함수의 호출주체가 명확하게 c다.

 

 

참고)

서두에 strict mode에서는 다르게 동작할 수 있음을 밝혔었는데, 그 이유는 strict mode에서는 보안상의 이유로 기본적으로 this에 window를 바인딩하지 않기 때문이다. (자세한 내용일 알고싶다면 해당 링크 참고해보길 바란다.)