use strict
를 사용한 엄격 모드에서는 window 객체 대신 undefined로 설정된다.아무튼 일반 함수의 this는 고정되지 않고 동적으로 결정된다는
게 포인트다.
화살표 함수의 this는 정적으로 결정된다. 화살표 함수의 this는 상위(부모) 스코프 값이 상속된다.
즉, 고정적으로 상위 스코프를 가리킨다는 말이다.
✋ 이벤트 핸들러에서 this
이벤트 핸들러 함수에서 this는 이벤트가 발생한 요소를 가리킨다.
아래 코드를 살펴보자.
이벤트 핸들러의 this는 이벤트가 발생한 요소를 가리키므로 첫번째 this는 box
를 가리킨다.
const box = document.querySelector('.box');
box.addEventListener("click", function() {
// this -> box
this.classList.toggle("opening");
setTimeout(function() {
// this -> window
this.classList.toggle("opening");
}, 500);
})
// Uncaught TypeError: cannot read property "toggle" of undefined
그렇다면 setTimeout 함수 내의 this는 무엇을 가리킬까?
일반 함수로 작성되었으므로 window
객체를 가리킨다. 따라서 window
객체에는 opening
class가 없으므로 오류가 발생한다.
이런 경우에 화살표 함수를 사용해 this가 상위(부모) 스코프에서 값을 상속받도록 하면 된다.
const box = document.querySelector('.box');
box.addEventListener("click", function() {
// this -> box
this.classList.toggle("opening");
setTimeout(() => {
// this -> box
this.classList.toggle("opening");
}, 500);
})
위 예제에서 이벤트 핸들러를 화살표 함수로 바꿔보자.
const box = document.querySelector('.box');
box.addEventListener("click", () => {
// this -> window
this.classList.toggle("opening");
})
화살표 함수의 this는 상위 스코프 값이 상속되며 고정이라는 걸 기억하자.
이벤트 핸들러를 화살표 함수로 사용하면 this는 이벤트가 발생한 요소가 아닌 window
를 가리킨다. 아마도 의도한 대로 코드가 동작하지 않을 것이다.
arguments는 함수에 전달된 인수 값을 담은 배열 객체다.
arguments는 함수 내부에서 접근이 가능하다.
function foo () {
console.log(arguments[0]);
}
foo("a", "b", "c"); // "a"
그런데 화살표 함수는 arguments에 접근하는 방식이 일반 함수와 다르다. 화살표 함수에서 arguments 객체는 부모 스코프의 값을 상속받는다. this와 비슷한 접근이라고 생각하면 된다.
const foo = () => {
console.log(arguments[0]);
}
foo("a", "b", "c");
// ReferenceError: arguments is not defined at foo
화살표 함수로 arguments에 접근하려면 아래와 같이 rest 파라미터를 사용해 명시적으로 작성하면 된다.
const foo = (...arg) => {
const pick = arg[0];
console.log(pick); // "a"
}
foo("a", "b", "c");
위 코드를 일반 함수로 작성하면 아래와 같다.
const foo = function() {
const pick = arguments[0];
console.log(pick); // "a"
}
foo("a", "b", "c");