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
가 된다.