This

This

코어 자바스크립트(정재남 저) 책을 기본으로 하여 자바스크립트를 공부하면서 내용을 정리하고자 한다.


03 This


자바스크립트에서 this 는 함수를 어떤 방식으로 호출하느냐에 따라 달라진다. 상황에 따라 달라지는 this에 관해 알아보자.

👉🏻 전역에서의 this

일단 기본적으로 this 가 뭘 나타내는지 보자.

this

console.log(this)를 출력하니 window 객체가 나온다. 밑에 있는 console.log(window)의 출력 결과와 같은 것을 볼 수 있다.

그렇다. 기본적으로 자바스크립트에서의 this는 전역객체 즉, window 객체를 뜻한다. (node.js 환경에서는 global 객체)

🔭 그럼 어떤 상황에서 this 의 값이 변화하는 것일까?

🪃 첫번째 상황 : 메서드로서의 호출

this1

위의 예시를 보면, callByName()의 구문은 함수 자체로 함수를 호출한 예시이고, magician.method()은 메서드로서 함수를 호출한 예시이다.

var로 선언한 변수 name은 전역객체의 프로퍼티가 된다. callByName()을 실행하면 함수 내부의 this 는 전역객체를 가리키고, 앞서 선언한 변수 name의 값인 Harry Potter를 출력한다.

그러나 magician.method()로 실행한 함수에서의 this 는 magician 객체가 된다. 객체 내부의 프로퍼티명 name을 찾아 그 값을 출력한다.

즉, 메서드로서의 함수를 호출할 때는 그 메서드 앞에 명시되어 있는 그 객체가 this 의 값이 된다.

🪄 메서드로서의 호출이란?

함수명(프로퍼티명) 앞에 .(dot)이 있으면 메서드로서의 호출이다.

위의 예시를 다시 보면,

magician 이라는 객체 안의 프로퍼티명으로 선언된 method에는 함수 magic이 할당되어 있다. method라는 프로퍼티명은 즉 함수명을 의미한다.


this2

함수를 프로퍼티로 가진 객체에 .(dot)을 붙여 함수명 (method)을 적어 호출하면 메서드로서 함수를 호출하는 방법이 된다.

즉, 함수명(프로퍼티명) 앞에 있는 객체가 호출한 대상이 되고 그렇기에 메서드로서 함수를 호출할 시 this.(dot) 바로 앞에 있는 그 대상, 그 객체가 this 가 되는 것이다.


this3

magic.magicA() 을 실행하면, this 는 바로 앞에 있는 magic 객체를 나타낸다. magic.theOther.magicB()를 실행하면 this 는 역시 바로 앞, theOther 객체를 나타낸다.


🪔 메서드 호출의 방식은 사실…

2가지 방법이 있다.

위에서는 .(dot)만을 얘기했는데 [](bracket) 방법도 있다. 역시나 결과는 같다. 그러나 보통은 .(dot)을 사용한다.

this4



🔖 Additional

this5

부연 설명으로

위의 예시처럼 name 변수를 const로 선언하면 this.name의 값은 나오지 않는다. const, let으로 선언된 변수는 전역 객체의 프로퍼티가 되지 않기 때문이다. this 를 출력하면 name 프로퍼티는 존재하지 않는다.

전역 변수는 되도록 사용하지 않는 것이 좋다. 함수를 만들 땐 외부 변수나 전역 변수를 사용하는 것보다 함수 내부에서 변수를 받고 이를 이용해 결과를 만들어내게 해야 테스트도 쉽고, 에러도 덜 만들어낸다.


🪃 두번째 상황 : 함수로서의 호출


앞서 함수로서의 호출의 예시를 잠깐 봤었다. 메서드로서의 함수 호출과 비교하면서.

this6

함수를 그 자체로 호출하면 모든 this 는 전역객체를 나타낸다.


🔦 자 그럼, 함수 내부의 함수에서는 어떤 일이 벌어지는지 살펴보자!

this7

🧩 위의 결과는 어떨까?


🏌️ 코드를 따라가보자.

magic.magicA()가 실행되면, 먼저 magicA 함수가 실행된다.

magicA 함수 내부의 첫번째 this 는 메서드로서의 호출로 magic 객체를 나타낸다.

this8


magicB()가 실행되면, magicB 함수 내부의 두번째 this 가 출력되는데,

this9

window 객체, 즉 전역 객체가 출력된다. 함수 호출 방식은 this 가 전역 객체를 가리키기 때문이다.


마지막으로 magic2.magicBB()가 실행되면, magicA 함수 내부에서 선언된 변수 magic2에 할당되어 있는 객체의 프로퍼티로 magicBB는 magicB와 동일한 함수이지만,

this10

this 는 magic2 객체를 가리킨다. 메서드로서의 호출 방식이기 때문이다.


💡 NOTICE

this 는 결국 어떤 방식으로 함수가 호출되느냐에 따라 그 대상이 정해진다.

함수 내부에서 this를 같은 함수로 호출하더라도 그 대상은 달라진다.


🤷🏻 그럼, 스코프처럼 함수 내부에서의 this를 상위 this에서 상속받아 사용할 수는 없을까? 더 편리할 것 같은데…

방법이 있다!

this11

this 를 다른 변수에 할당하여 사용하면 가능하다. 위의 예시처럼 that 이라는 변수에 this를 할당하고 그 변수를 사용하면 상위 this를 가리킨다.


💁🏻 더 간단한 방법도 있다!


this12

ES6의 화살표 함수를 이용하면 상위 this 를 그대로 활용한다.



🪃 세번째 상황 : 콜백 함수로서의 호출


콜백 함수 역시 함수이기 때문에 원칙적으로 this 는 전역객체를 가리킨다. 그러나 별도로 함수가 this 지정하는 경우가 있다. 그럴 경우는 지정된 대상이 this 대상이 된다.

this13

예시의 forEach 메서드는 콜백 함수를 인수로 받아 실행하는데 this 는 window 객체를 가리킨다.

addEventListener 메서드는 역시 콜백 함수를 인수로 받아 실행되었으나, this 는 해당 이벤트가 실행되는 주체인 상위 엘리먼트가 그 대상이 된다.



🪃 네번째 상황 : 생성자 함수로서의 호출


생성자 함수는 공통된 성질을 가진 객체를 생성하는 함수이다. 객체가 붕어빵이라면 생성자 함수는 붕어빵을 찍어내는 틀이라고 할 수 있다. new 키워드를 사용하여 함수를 호출하면 그 함수는 생성자 함수로 인식된다.


this14

생성자 함수에서의 this 는 새로 만들 객체 그 자신이 된다.

a 변수로 선언된 새로운 인스턴스 객체 그 자신인 a가 this 인 것이다.


코드 참고하려면


👉🏻 다음 장에서 이어서 설명 👉🏻 Next Page


참고자료