
this
자바스크립트에서의 this는 함수의 현재 실행 문맥이다.
함수 실행에서의 this
함수 실행에서의 this는 전역 객체다. 전역 객체는 실행 환경에 따라 결정되는데, 웹 브라우저에서는 window가 전역 객체다. 아래의 예시를 보자.
1 | function sum(a, b) { |
7행에서 sum함수를 호출한 결과를 obj라는 변수에 넣었다. sum함수의 매개변수로 15와 16을 전달했고, 1행의 sum함수가 실행된다.
이 때, 7행에서 sum함수를 호출할 때의 this는 전역 객체인 window이므로 2행에서 this === window의 결과는 true이다.
그 후, 3행에서 window객체의 myNumber에 20을 저장한 뒤, 4행에서 15와 16을 더하여 반환한다. 그 반환 값은 7행의 obj에 저장되기 때문에, 8행의 결과는 31이다.
그리고 9행의 obj.myNumber은 정의한 적이 없기 때문에 undefined이며, 10행의 window.myNumber은 아까 3행에서 20으로 저장했기 때문에 20을 출력한다.
그렇다면 이번엔 다음 예제를 보자.
1 | function sum(a, b) { |
이번엔 sum형 객체로 obj를 생성했다. 객체를 생성했을 때의 this는 그 객체 자신이 되기 때문에 2행에서의 this는 obj이다. 따라서 this === window의 값은 false이다.
3행에서 this.myNumber은 obj.myNumber을 의미하기 때문에 obj.myNumber에 20을 저장한다.
그리고 obj는 객체이기 때문에 7행에서 obj의 출력 결과는 [object Object]이다.
8행의 실행 결과는 아까 저장한대로 20이며, window.myNumber은 정의한 적이 없기 때문에 undefined이다.
엄격 모드 함수 실행에서의 this
엄격 모드에서 함수 실행에서의 this는 undefined이다. 그리고, 엄격 모드는 현재 스코프 뿐만 아니라 내부 스코프에서도 적용된다.
1 | function sum(a, b) { |
내부 함수에서의 this
내부 함수의 문맥은 외부 함수의 문맥에 의존되는 게 아니라 오로지 실행 환경에 좌우된다. 아래의 예시를 보자.
1 | var numbers = { |
numbers.sum()은 객체 내에 있는 메소드를 실행하는 것이기 때문에 sum메소드 내의 문맥은 numbers객체다. 즉, 5행에서 외부 함수의 this는 numbers인 것이다. 하지만 calc함수는 sum함수 내부에 정의되었다. 이 때 this는 window이다. 또한 이 때 9행에서 this가 window이기 때문에 16행의 출력결과는 NaN이 되는 것이다.
이러한 문제를 해결하기 위해서 calc함수도 sum메소드와 동일한 문맥 상에 있어야 한다. 그래야 numA와 numB속성에 접근할 수 있기 때문이다. 이를 해결하려면 call이나 apply또는 bind를 사용하면 된다. 여기서는 call메소드를 사용하여 해결해보겠다.
1 | var numbers = { |
11행의 this는 외부 함수인 sum메소드에 속하기 때문에 numbers이다. 따라서 calc.call(this)는 numbers객체에 calc라는 메소드를 등록해주는 셈이기 때문에, calc메소드의 this도 numbers가 된다.