슈퍼맨에게는 특별한 능력들이 있다. 저 객체에 하늘을 나는 능력을 추가해 보자.
이렇게 객체에 함수를 추가하고 superman.fly()를 호출해 보면 슈퍼맨이 날아간다고 로그에 찍힌다. 이렇게 객체 프로퍼티로 할당된 함수를 메서드라고 한다. 여기에서 fly 함수가 superman 객체의 메서드인 것이다.
단축 구문으로도 작성할 수 있다. 양쪽의 코드는 같다. 메서드의 function 키워드는 생략 가능하다.
객체의 메서드의 관계를 살펴보자. user 이름은 'Mike'이고 sayHello라는 메서드를 가지고 있다. 이 메서드 로그에 객체의 name 프로퍼티를 넣고 싶다면 어떻게 하면 될까?
user의 name이니까 이렇게 하면 된다. 하지만 이 방식은 문제가 발생할 수 있다. 이 부분은 잠시 후 코드로 살펴보자.
이럴 때는 this라는 키워드를 쓰면 된다. user.sayHello()를 호출하면 점 앞에 있는 user가 sayHello 메서드의 this가 된다.
예제를 만들어 보자. 소년과 소녀 변수 그리고 sayHello 함수를 만들었다. 여기에서 this는 아직 결정되지 않았다. 어떻게 호출하느냐에 따라 달라지게 된다.
이제 이 함수를 각 개체의 메서드로 넣어준다.
그리고 호출해본다. this는 실행하는 시점, 즉 런타임에 결정된다. sayHello 함수의 this는 점 앞에 있는 개체이다. 그래서 boy의 sayHello 메서드의 this.name은 Mike이고 girl의 경우 Jane이 된 것이다.
만약 저 함수를 화살표 함수로 선언했다면 동작이 전혀 달라지게 된다.
화살표 함수는 일반 함수와는 달리 자신만의 this를 갖지 않는다. 화살표 함수 내부에서 this를 사용하면, 그 this는 외부에서 값을 가져온다.
이렇게 화살표 함수로 메서드를 만들고 코드를 실행하면, this는 점 앞의 boy 객체를 가리키지 않는다. 화살표 함수는 this를 가지고 있지 않기 때문에 여기에서 this를 쓰면 전역객체를 가리키게 된다. 참고로 브라우저 환경에서 전역객체는 window이고, Node.js에서는 global이 된다.
자바스크립트에서 this는 상당히 복잡하다. 학습자들이 가장 어려워 하는 부분 중이 하나이기도 하다.
코드로 살펴보자. boy라는 객체가 있고 이름은 Mike이다. showName을 하면 이름을 보여주는데, 처음에 배웠던 것처럼 boy.showName을 하면 이렇게 자기 이름을 보여준다.
이제 man이라는 변수를 새롭게 만들고 여기에 boy를 할당한다. 이렇게 되면 객체를 새로 만든 건 아니고, 객체가 하나 있는데 boy로도 접근할 수 있고 man으로도 접근 가능한 것이다. 그러니까 사람은 Mike 한 명인데 별명이 두 개인 셈이다.
예를 들어 man의 이름을 Tom으로 바꾸면 boy의 이름도 Tom으로 찍히는 걸 볼 수 있다.
그러면 man.showName()이 잘 동작하는지 확인해보자. 결과는 Mike로 잘 나오고 있다.
이 상태에서 boy를 null로 만들어보자. 지금까지 Mike에 접근할 수 있는 게 boy와 man이었는데 boy는 null로 만들었고 이제 man으로만 접근할 수 있다. 이 상황에서 man에 showName()을 하면 어떻게 될까?
name이 없다는 에러가 발생한다. 지금 boy의 name은 사라졌다. boy는 지금 null을 가지고 있고 name도 없어졌고 showName()도 없어졌다. 그래서 man.showName()이 동작할 수 없는 것이다.
이럴 때는 콘솔의 boy를 this로 바꿔주면 된다. 왜냐하면 메서드의 this는 해당 객체를 가리키기 때문이다. 결론적으로 메서드에서는 개체명을 직접 써주는 것보다는 this를 활용하는 게 좋다.
이번에는 화살표 함수를 써보자. 지금 boy라는 객체가 있고 this를 찍어주는 sayThis라는 메서드가 있다. 실행해보면 객체를 반환해준다. 여기에서 this는 객체를 의미하는 것이다.
여기에서 메서드를 화살표 함수로 바꾸면 실행했을 때 오류가 뜬다. 콘솔에 윈도우가 뜬 것이다. 화살표 함수로 메서드를 작성하면 this는 boy를 가리키는 게 아니라 window 전역객체를 가리키게 된다. 그래서 객체 메서드를 작성할 때는 화살표 함수로 작성하지 않는 게 좋다.
출처: 코딩앙마, 자바스크립트 기초 강좌 #13 - 객체(Object) - method, this