자바 스크립트의 this는 객체 지향 언어인 자바의 this의 개념이 사뭇 다르기에 처음 접했을때부터 지금까지도 종종 햇갈리는 상황이 벌어진다. 자바의 this는 인스턴스 자신을 가리키는 참조변수로서 this를 통해 클래스의 멤버 변수 접근을 할 수 있었다. 그러나 자바스크립트의 this는 함수 호출 시 함수가 어떻게 호출 되었는지에 따라 this 값이 동적으로 결정되기 때문에 많은 혼란을 야기한다...
먼저 간단한 예제를 통해 this의 개념에 접근해보자. 최상단엔 name이란 전역 (window 객체)변수를 선언 하였고, this의 name을 출력하는 thisTest라는 함수와, name과 thisTest함수를 담고있는 obj라는 객체가 있다.
먼저 하단에서 thisTest함수를 직접적으로 호출했을때의 this.name은 전역 변수인 "kim"이며, obj의 printName을 통해서 thisTest을 호출했을때의 this.name은 'Park'이다. 간단한 예제 이지만, 자바스크립트의 this는 this를 사용하는 해당 함수를 '어떻게' 실행 했느냐에 따라 바뀐다는것을 알 수 있다. 이제 함수 실행 방식에 따라 this가 어떻게 바뀌는지 살펴보자.
위 예제는 this를 출력하는 함수인 regular함수를 기본적인 함수 호출 방식으로 호출한 예제이다. this는 호출방식에 따라 달라진다고 했으니, 전역에서 직접 적으로 호출 시 this는 전역 객체 (브라우저에선 window 객체)가 된다.
('use-strict'모드 에선 무조건 undefined가 출력)
위 예제도 마찬가지로 일반적인 함수 호출방식으로 foo를 호출 했기 때문에 this.num의 값은 전역 변수 num의 100이 된다. foo를 통해 test가 호출되었기 때문에 10이 출력되지않을까 하고 햇갈릴 수 있지만, 결국 호출 근본지는 전역이라는 사실을 상기 한다면, 100이 호출되는것이 맞다.
이번 예제에서는 people의 메서드 print가
people.print
를 통해 호출되는데, 이럴 경우 this는 people을 가리키게 된다. Dot Notation 방식으로 호출 시에는 대부분의 경우 dot(.)의 앞 부분이 this가 된다고 한다.(이 부분).method
위 예제를 보면 좀더 이해에 도움이 될것이다.
call, bind, apply는 자바 스크립트 함수의 프로토타입 메서드들이다. (prototype 메서드 이므로 어떤 함수던 간에 사용할 수 있다.)
이 메서드들을 이용하면 함수 호출 시 this값을 직접 지정해줄 수 있다. 먼저 특징이 비슷한 call과 apply 메서드 부터 살펴보자.
call과 apply 둘다 첫번째 인자로 변수를 전달하면 해당 값으로 this가 정해진다. call과 apply의 유일한 차이점은, 첫 번째 인자(this를 대체할 값)을 제외하고 호출할 함수에 필요한 인자를 기재하는 방식이다. call과는 달리 apply 메서드는 두 번째 인자에 하나의 배열을 통해 사용할 인자를 넣어줘야한다.
bind 메서드는 call, apply 메서드 처럼 함수를 바로 실행하지않기 때문에 변수에 할당이 가능하며, 이를 통해 미리 지정해둔 this값을 가진 함수를 원하는 타이밍에 변수를 통해 사용할 수 있다.