this 가 정해지는 규칙
1. 함수 실행시, this 는 전역 객체이다.
2. 함수가 객체의 프로퍼티일 경우, this는 해당 객체를 의미한다.
3. new 생성자로 함수 호출시, this는 new 키워드로 만들어진 객체이다.
4. call, apply 메소드로 간접 실행시, this 는 호출하는 쪽에서 지정한 객체이다.
- 코드 1 -
- 코드 1 실행 결과 -
- price 함수 실행시, this 와 window는 같음을 알 수 있다.
- 코드 2 -
- 코드 2 실행 결과 -
- pizzas.order() 호출 시, order는 pizzas의 프로퍼티이기 때문에 this 는 pizzas라는 객체가 된다.
따라서, order 안에서 this.pizzaA 를 찍어보면 예상대로 25000이 출력된다.
여기까지는 무난하다.
- 헷갈리는 부분은 pizzas.order 안에서 호출하는 getPrice 라는 내부함수의 콘텍스트이다.
내부 함수의 콘텍스트는 외부 함수의 콘텍스트에 의존하는 것이 아니라 실행 환경에 의해 결정된다.
따라서, getPrice 안의 this는 Window를 의미하며, this.pizzaA는 undefined 이다.
this.pizzaA + this.pizzaB 는 undefined 들의 합을 의미하므로 NaN 이 출력되는 것이다.
- 그렇다면, 기대했던 대로 pizza.order 내부의 getPrice() 호출시에 NaN이 아닌 55000 이 제대로 출력되게 하려면 어떻게 해야할까?
1차적으로 getPrice 함수 내의 this가 window가 아닌 pizzas객체를 의미해야한다.
call, apply 메소드를 이용하면 함수 실행시의 this를 지정할 수 있다.
- 코드 3 -
- 코드 3 실행 결과 -
- call 메서드는 첫번째 argument로 들어온 값으로 적용된 콘텍스트의 값을 수정해준다.
- order 콘텍스트의 this는 pizzas이기 때문에 getPrice의 this도 pizzas가 된다. 따라서 55000이 출력되게 된다.
call과 apply의 차이는 argument를 넘기는 방법이다. 상황에 맞춰 필요한 메소드를 사용하면 되겠다.
call |
각각의 인자를 넘긴다. 콤마로 구분한다. 예) fn.call(o, arg1,arg2,...,argN); |
apply |
배열이나 객체 형태로 넘길 수 있다. 인자가 가변적일 때, 유용하다. 예) fn.apply(o, [args]); |
2부 끝.