this는 실행 컨텍스트가 생성될 때 함께 결정된다.
this는 this가 선언되는 환경과 상관없이 함수를 호출할 때 결정된다.
전역 공간에서의 this
- 전역객체를 가리킴. (브라우저-window/ nodejs-global)
- 전역 공간의 실행 컨텍스트를 생성하는 주체가 전역객체이기 때문.
- 전역변수를 선언하면 Js엔진은 이를 전역객체의 프로퍼티로 할당한다.
- 자바스크립트의 모든 변수는 사실은 특정 객체의 프로퍼티로서 동작.
- 전역 함수호출이나 변수사용은 window가 생략됐다고 봐도 무방하다.
함수를 호출하는 방법
객체의 메서드로 호출할 경우에만 메서드로 동작, 그렇지 않으면 함수로 동작한다!
함수를 호출할 때 그 함수 이름 앞에 객체가 명시되어있는 경우에만 메서드로 호출한 것.
그렇지 않은 모든 경우는 함수로 호출한 것.
1. 함수로서 호출
- 그 자체로 독립적인 기능 수행.
- .을 사용해 객체를 지정하지 않고 호출.
- 호출한 주체의 정보를 알 수 없기 때문에 this가 지정되지 않는다.
- 실행 컨텍스트 활성화 시, this가 지정되지 않은 경우 this는 전역객체를 바라본다.
2. 메서드로서 호출
- 자신을 호출한 대상 객체에 관한 동작 수행 (.앞에 명시한 객체)
- this는 호출한 주체(객체)가 된다.
*메서드의 내부 함수도 앞에 어떤 객체를 명시해서 사용했냐에 따라 this가 달라진다.
다양한 경우의 this 바인딩
1. this를 바인딩하지 않는 화살표함수
es6에서 함수 내부의 this가 전역객체를 바라보는 문제를 보완하고자 도입함.
- 실행 컨텍스트 생성 시 this바인딩 과정 자체가 빠지게 됨.
- 상위 스코프의 컨텍스트에서 this를 찾아 사용함.
- 다른 함수들과 달리 선언하는 시점에서 this가 결정됨.
2. 콜백함수 내부에서의 this
콜백함수란?
다른 함수에게 제어권을 넘긴 함수.
ex) 함수a의 제어권을 다른 함수b에게 넘겨주는 경우의 함수 a가 콜백함수이다.
콜백함수의 this
- 무조건 어떤 것이라고 정의할 수 없음.
- 기본적으로 전역객체를 가리킴.
- 제어권을 가진 함수가 특정 값으로 지정하면 그 값이 됨.
예시
setTimeout과 forEach는 this를 따로 지정하지 않음.
addEventListner는 자신의 this를 참조하도록 함.
3. 생성자 함수 내부에서의 this
- 함수 호출 시 앞에 new키워드를 붙이면 객체를 생성하는 생성자 함수가 됨.
- 생성자로 호출된 함수 내부의 this는 반환 값인 인스턴스를 가리킴.
명시적으로 this바인딩하는 방법
1. call()
매개변수로 넣어진 객체를 자신을 호출하는 함수 내부의 this로 바인딩해주는 함수.
func.call(thisArg, arg1, arg2)
- 자신을 호출하는 주체의 함수를 즉시 실행함.
- 첫 번째 인자로 this로 바인딩할 객체를 넣어줌.
- 나머지 인자들을 호출할 함수의 매개변수로 넣어줌.
2. apply()
func.apply(thisArg,[arg1, arg2])
- call과 같지만 나머지 인자들을 배열의 형태로 받음.
3. bind()
call과 비슷하지만 넘겨받은 thisArg와 인수들을 적용한 새로운 함수를 반환하기만 하는 함수.
- this미리 적용되고 파라미터가 일부 적용된 함수를 반환하는 것.
→ 반환된 새로운 함수를 호출 할 때 인수를 넘기면 bind함수에 넣은 인수들에 뒤이어서 등록됨.
- 반환받은 함수엔 name속성이 포함되는데 원본함수 이름에 접두사 ‘bound’가 붙여진 이름이 할당되어있다.
→ bind가 적용된 새로운 함수라는 의미를 나타내므로 명시적이다.
상위 컨텍스트의 this를 내부함수나 콜백 함수에 적용하기
내부 함수에 적용
*속해져 있는 객체가 없기 때문에 대상 객체를 명시할 수 없다.
- 내부함수를 실행할 때
call/apply(상위this)
를 붙여 실행한다.
- 내부 함수 자체를
bind(상위this)
를 실행해 변수에 저장해 사용한다.
- 내부함수를 화살표함수 형태로 만든다. → 가장 간단한 방법
콜백함수 적용
- 콜백함수를 전달할 때
bind(상위this)
를 실행한 후 반환된 함수로 전달한다.
- 화살표함수를 전달한다.
별도의 인자로 this를 받는 경우
콜백 함수를 인자로 받는 메서드 중 일부는 인자로 this로 지정할 객체를 받을 수 있다.
주로 콜백 함수를 받아 반복 실행시켜야하는 메소드의 경우 해당한다.
forEach(callback, thisArg)
, map
, filter
, find