모든 테스트는 Strict 모드에서 진행되었다.
전역 공간에서 this
-
브라우저에서 this를 출력하면 window 객체가 나온다.
-
Node.js에서 this를 출력하면 global 객체가 나온다.
함수 내부에서 this
-
함수 내부에서 this는 기본적으로 전역 객체를 가리킨다.
-
하지만 바꿀 수 있다.
메소드 내부에서 this
- 메소드 바로 앞에 있는 부분까지가 this이다.
-
메소드와 친구인 함수를 생각할 땐 전역 객체(window, global)의 메소드라고 생각하면 된다.
-
즉 함수()는 전역 객체.함수()의 형태이므로
함수()는 전역 객체의 메소드라고 생각하면 된다.
내부 함수에서 우회법
-
obj.b()에서의 b()는 obj가 호출한 메소드이기 때문에 obj안에 있는 a값이 출력된다. (= 20)
-
하지만 c()는 그냥 함수이기 때문에 전역 객체의 a값이 출력된다. (= 10)
-
그렇다면 c()함수안에서 this를 obj를 가리키게 할 수 없을까?
-
Scope Chain을 통해 우회가 가능하다.
-
b() 메소드에서 this를 self라는 변수에 담고
-
c() 함수안에서 self라는 변수를 사용한다.
물론 반드시 self라는 변수를 사용하는 것은 아니다. -
c() 함수안에서 사용된 self 변수는 자신의 Scope안에서 self를 찾게 되고
-
c() 함수안 없기 때문에 Scope Chain에 의해 위로 올라가서 찾게 된다.
(= b() 메소드에서 선언된 self 변수를 사용한다.)
CallBack에서 this
-
기본적으로 함수 내부에서와 동일하다.
-
하지만 call, apply, bind를 통해 this를 바꿀 수 있다.
-
아래 코드의 결과 값은 모두 동일하다.
- 공식 문서를 보자.
-
맨앞에 thisArg는 모두 동일하다.
-
그리고 thisArg 변수는 개발자가 직접 명시하여 this를 명시한 값으로 인식시키게 된다.
-
call과 bind는 두번째 인자부터 무한대로 입력이 가능하다.
-
apply는 두번째 인자로 배열이 온다.
-
call과 apply의 차이는
두번째 부터 무한대로 입력으로 받느냐
하나의 배열로 받느냐 이다.
- call과 apply는 즉시 호출이다.
- 반면 bind는 새로운 함수를 생성한다.
- 그렇기 때문에 다음과 같이 변수에 담아 사용한다.
- 다른 예를 보면
-
b: function(cb)에서의 cb는 callback이 된다.
-
그리고 그안에서 cb()를 호출하면 다음 함수가 호출이 된다.
var callback = function(){
console.dir(this)
}
-
이때 단순히 cb()를 호출했기 때문에 그 자체는 함수가 되고
-
함수안에서의 this는 기본적으로 전역 객체를 가리키기 때문에 window가 출력된다.
-
마찬가지로 cb는 callback이 된다.
-
하지만 cb.call(this)에서의 this는
-
obj.b(callback)형태로 b()함수를 호출했기 때문에 this는 obj가 된다.
- 또 다른 예를 보자.
- bind 함수를 사용하여 this의 값을 명시적으로 지정해줬다.