JavaScript - This

Marisol Benitez from Unsplash

자바 스크립트에서 this는 무엇을 의미하는걸까? 아래의 코드를 개선하는 과정을 통해 this가 가리키는 것이 무엇인지를 알아보자.

1
2
3
4
5
6
7
8
9
const me = {
name: 'youngjin',
age: 31,
hello:function(name, age) {
return 'Hello, My name is '+name+'. I am '+age+'.';
}
}

console.log(me.hello(me.name, me.age));

위의 코드는 name, age, hello()라는 속성을 갖는 오브젝트이다. 그리고 이 오브젝트를 이용하여 콘솔에 이름와 나이를 출력하는데, 이 때 외부에서 값을 주입받아서 출력을 하고 있다.

언뜻봐도 비효율적인 코드이다. 이미 내부에서 속성으로 갖고있는 값을 굳이 외부에서 주입받을 필요가 있을까? 위의 코드를 조금 개선해보도록 하겠다.

1
2
3
4
5
6
7
8
9
const me = {
name: 'youngjin',
age: 31,
hello:function() {
return 'Hello, My name is '+me.name+'. I am '+me.age+'.';
}
}

console.log(me.hello());

이름과 나이를 외부에서 주입받지 않고, 내부 속성에 담겨있는 값을 호출했다. 이렇게하니 비효율성을 조금 덜어낸것 같다.

그런데 만약 이 오브젝트의 이름을 person 으로 바꾸게 되면 어떨까? 오브젝트 이름뿐 아니라 내부 속성을 호출하는 모든 함수에서 변경을 해야할 것이다. 예시 코드 속 오브젝트는 내부 함수가 하나밖에 없는 작은 오브젝트지만, 만약 내부 속성을 호출해서 사용하는 함수를 수십개 가진 오브젝트라면 어떻게 변경해야 할까?

한마디로 위의 코드는 변경에 취약한 코드이다. 어떻게 더 개선할 수 있을까?

이 때 등장하는 키워드가 This이다. this를 사용해서 변경에 유연한 오브젝트로 개선해보겠다.

1
2
3
4
5
6
7
8
9
const person = {
name: 'youngjin',
age: 31,
hello:function() {
return 'Hello, My name is '+this.name+'. I am '+this.age+'.';
}
}

console.log(person.hello());

오브젝트 내부를 호출할 때 사용하는 키워드로 오브젝트 명 대신 this 키워드를 사용했다. 이렇게 되면 앞으로 오브젝트 명이 바뀔때마다 내부 속성 호출부를 수정하지 않아도 된다.

this가 무엇을 가리키길래 이런 역할을 할 수 있는걸까?

1
2
3
4
5
6
7
8
9
10
11
12
const person = {
name: 'youngjin',
age: 31,
hello:function() {
return 'Hello, My name is '+this.name+'. I am '+this.age+'.';
},
whoIsThis:function() {
return this;
}
}

console.log(person.whoIsThis());

this를 반환하는 함수를 오브젝트에 추가해서 콘솔에 출력해보았다.

this는 오브젝트 자신을 가리키는 키워드였다. 오브젝트 자신을 가리킴으로써 내부 속성에 접근할 수 있던 것이다.

웹 브라우저의 개발자도구를 열어서 콘솔창에서 this를 입력하면 Window 객체를 반환하는 것도 확인할 수 있다.

이번엔 이름과 나이를 외부에 주입받아서 이를 속성이 참조하도록 하고, 속성을 호출해서 인삿말을 출력할 수 있도록 코드를 리팩토링해보겠다.

외부에서 변수를 받아서 속성에 주입하기 위해서는 함수(function)가 필요하다.

1
2
3
4
5
6
7
8
9
10
function person(name, age) {
name= name,
age=age,
hello=function() {
return 'Hello, My name is '+this.name+'. I am '+this.age+'.';
}
}

const me = new person('youngjin',31);
console.log(me.hello);

여기까지 작성하고 콘솔에 출력하면 undefined가 출력된다. hello()라는 함수를 찾지 못한 것이다.

person의 내부 속성에 this를 선언하면 함수를 올바르게 인식할 것이다.

1
2
3
4
5
6
7
8
9
10
function person(name, age) {
this.name= name,
this.age=age,
this.hello=function() {
return 'Hello, My name is '+this.name+'. I am '+this.age+'.';
}
}

const me = new person('youngjin',31);
console.log(me.hello());

이렇게 하면 정상적으로 출력된다. this 키워드를 통해서 person 객체의 내부속성으로 argument를 대입하여 이를 외부에서 호출할 수 있었다.