1. 화살표함수의 this
일반함수는 자신의 코드블럭에 자신의 this를 가질 수 있다.
그러나 화살표함수는 일반함수와 달리 자신의 this를 가질수 없다라는 규칙이 있다.
let user = {
getName: ()=>{
console.log(this);
},
};
user.getName();
this의 가장 가까운 일반함수를 찾아보자.
전역함수이므로 this는 전역함수의 this가 되는 것이고 연결된 객체는 window다.
2. 비동기함수내 this
먼저 객체 프로퍼티의 개념에대해 이해하자
프로퍼티는 데이터프로퍼티와 접근자프로퍼티로 나누어지며 접근자프로퍼티는 getter, setter라고 이전에 설명했다.
데이터프로퍼티는 값을 가지고있는 프로퍼티이며 원시값 또는 객체를 참조하기위한 메모리번지값을 가지고 있다.
함수는 객체의 일종이고 타입이 함수이면 메소드라고 부를 뿐이다.
user.getName; 속성접근자가 user의 getName프로퍼티에 접근하여 값을 반환한다.
getName이 메소드라면 함수가 존재하는 메모리번지값을 반환한다.
user.getName(); // user의 getName프로퍼티에 접근하여 호출하고 결과값이 반환된다.
let user = {
getName:function(){
console.log(this);
}
};
setTimeout(user.getName, 1000);
setTimeout은 콜백을 이벤트루프에 추가하는 역활만하는 비동기함수다.
user.getName은 함수이므로 setTimeout함수가 요구하는 콜백인자의 타입에 맞는다.
만약 user.getName()를 전달하면 함수결과값이 전달되기 때문에 에러가 발생한다.
setTimeout(user.getName, 1000);에서 우리는 1초후에 console.log(this);로 user객체가 출력되길 기대할것이다.
그러나 window객체가 출력된다.
자바스크립트 함수의 유연성덕분에 발생한 결과다.
setTimeout은 이벤트루프에 콜백을 추가하고 호출책임은 이벤트루프에 위임한다.
콜백이 호출객체없이 함수가 있는 메모리번지값만 전달되었기 때문에 이벤트루프에의해 호출되어 전역객체가 호출주체가 된것이다.
setTimeout에 this가 있는 함수를 전달할때
호출되길 원하는 객체로부터 메소드가 호출되도록 전달해야 한다.
setTimeout(()=>user.getName(), 1000);
user.getName();을 감싸는 래퍼함수의 메모리번지값을 전달하고 호출될때 내부의 user.getName();구문이 수행된다.
속성접근자는 user객체에 getName프로퍼티를 찾아 user에 getName프로퍼티를 연결한다. 함수라면 호출한다.
래퍼함수는 실제로 실행되어야할 구문을 감싸는 단순한 함수값역활만 하는 것이다.
this가 있는 화살표함수를 객체프로퍼티로 사용하면
this가 있는 화살표함수를 객체프로퍼티로 사용하면 가장 가까운함수에 연결되 객체를 참조하게되어 좋지 않은 방법이다.