JavaScript에서의 this에 대해 정리한 내용입니다.
JavaScript의 this는 자유롭다
- 자바스크립트에서 함수의 this 키워드는 다른 언어들과 비교하여 조금 다르게 동작한다
- this 값은 런타임에 결정된다
- 대부분의 경우 this 의 값은 함수의 호출하는 방법에 의해 결정된다 (이 부분이 포인트)
- this는 현재 실행되는 코드의 실행 컨텍스트를 가리킨다
컨택스트란?
- JS는 스크립트 언어로 인터프리터에 의해
줄 단위로 읽혀서 해석되어 실행된다
- 인터프리터에 의해 현재 실행되는 자바스크립트의 환경을
"실행 컨텍스트" 라고 한다
- 자바스크립트 내부에서 이러한 실행 컨텍스트를 스택으로 관리하며
실행되는 시점에 자주 변경되는 실행 컨택스트를 this가 가리킨다
-
즉, 누가 호출했느냐에따라 this가 바뀌게 된다
- 동일한 함수라도 다른 객체에서 호출했다면 ‘this’가 참조하는 값이 달라진다는 것을 의미한다
- 실행하는 동안 할당에 의해 설정될 수 없고 함수가 호출될 때마다 다를 수 있다
function 에서의 this
const someone = {
name: 'lighthouse',
whoAmI: function () {
console.log(this);
}
};
someone.whoAmI();
// someone 객체가 출력 {name: "lighthouse", whoAmI: ƒ}
const myWhoAmI = someone.whoAmI;
myWhoAmI(); // window 객체가 출력
// btn이 호출하였으므로 button 엘리먼트가 출력
const btn = document.getElementById('btn');
btn.addEventListener('click', someone.whoAmI); // button 엘리먼트가 출력
btn.addEventListener('click', myWhoAmI); // button 엘리먼트가 출력
this 바인딩
- Function.prototype.bind() - JavaScript | MDN
- 함수의 this 값이 함수가 어떻게 호출되었는지와 무관하게 this를 고정시키는 것이 바로
bind()
메소드이다.
const bindedWhoAmI = myWhoAmI.bind(someone);
// 모두 someone 객체가 출력
btn.addEventListener('click', someone.whoAmI);
bindedWhoAmI();
Function.prototype 객체의 메서드인 call, apply, bind 를 통해 명시적으로 this를 바인딩해 줄 수도 있다.
자유로운 this가 만드는 결과
-
다른 언어를 사용하다 자바스크립트로 넘어온 개발자는 this를 혼동하기 쉽다.
- this는 항상 메서드가 정의된 객체를 참조할 것이라고 착각하기 때문이다.
- 이런 개념을
bound this
라고 한다.
-
자바스크립트에서 this는 런타임에 결정된다.
- 메서드가 어디서 정의되었는지에 상관없이 this는 ‘점 앞의’ 객체가 무엇인가에 따라 ‘자유롭게’ 결정된다
-
이렇게 this가 런타임에 결정되면 좋은 점도 있고 나쁜 점도 있다.
- 함수(메서드)를 하나만 만들어 여러 객체에서 재사용할 수 있다는 것은 장점이지만
- 이런 유연함이 실수로 이어질 수 있다는 것은 단점이다.
-
자바스크립트가 this를 다루는 방식이 좋은지, 나쁜지는 우리가 판단할 문제가 아니다.
- 개발자는 this의 동작 방식을 충분히 이해하고 장점을 취하면서 실수를 피하는 것에 집중할 필요가 있다.
this가 없는 화살표 함수
-
화살표 함수가 나오기 전까지는 모든 새로운 함수는 어떻게 그 함수가 호출되는지에 따라 자신의 this값을 정의했다
- 해당 함수가 생성자인 경우에는 새로운 객체
- 엄격 모드 함수 호출에서는 undefiend
-
화살표 함수는 일반 함수와는 달리 ‘고유한’ this를 가지지 않는다.
- 화살표 함수에서 this를 참조하면, 화살표 함수가 아닌 ‘평범한’ 외부 함수에서 this 값을 가져온다
- 아래 예시에서 함수
arrow()
의 this는 외부 함수user.sayHi()
의 this가 된다
let user = {
firstName: 'lighthouse',
sayHi() {
let arrow = () => alert(this.firstName);
arrow();
}
};
user.sayHi(); // lighthouse
- 단순히 코드량이 줄어드는 것 외에 별개의 this가 만들어지는 건 원하지 않고
- 외부 컨텍스트에 있는 this를 이용하고 싶은 경우 화살표 함수가 유용하다
정리
-
자바스크립트에서 함수의 this 키워드는 다른 언어들과 비교하여 조금 다르게 동작한다
- this 값은 런타임에 결정된다
- 대부분의 경우 this 의 값은 함수의 호출하는 방법에 의해 결정된다 (이 부분이 포인트)
- 즉, 누가 호출했느냐에따라 this가 바뀐다
-
함수의 this 값이 함수가 어떻게 호출되었는지 개의치 않고 설정할 수 있는 bind 메소드이다
- 호출된 값과 무관하게 this를 묶어버릴 수 있는 것이 바로 bind 메소드
-
다른 언어를 사용하다 자바스크립트로 넘어온 개발자는 this를 혼동하기 쉽다.
- this는 항상 메서드가 정의된 객체를 참조할 것이라고 착각하기 때문이다.
- 이런 개념을 ‘bound this’라고 함.
- 이렇게 this가 런타임에 결정되면 좋은 점도 있고 나쁜 점도 있다.
- 함수(메서드)를 하나만 만들어 여러 객체에서 재사용할 수 있다는 것은 장점이지만
- 이런 유연함이 실수로 이어질 수 있다는 것은 단점이다.
- 개발자는 this의 동작 방식을 충분히 이해하고 장점을 취하면서 실수를 피하는 것에 집중할 필요가 있다.
-
화살표 함수는 일반 함수와는 달리 ‘고유한’ this를 가지지 않는다.
- 화살표 함수에서 this를 참조하면, 화살표 함수가 아닌 ‘평범한’ 외부 함수에서 this 값을 가져온다