프로젝트에서 전체 선택 버튼을 구현하던 중, 이벤트 리스너 함수를 일반 함수에서 화살표 함수로 변경하자 동작이 실패했습니다. 다음은 문제 코드입니다
function AllCheck() {
for (let i = 0; i < $AllCheckBox.length; i++) {
$AllCheckBox[i].checked = this.checked;
console.log(this); // 이벤트 리스너의 this는 무조건 변수의 html 값
}
}
const AllCheck = () => {
for (let i = 0; i < $AllCheckBox.length; i++) {
$AllCheckBox[i].checked = this.checked;
console.log(this);// 화살표 함수는 부모 함수를 this로 가짐, window가 됨
}
}
$checkAll.addEventListener("change", AllCheck);
일반 함수에서는 this가 이벤트 리스너의 DOM 요소($checkAll)를 가리키지만, 화살표 함수는 정의 시점의 렉시컬 스코프의 this (여기서는 window)를 가리킵니다. window.checked는 undefined이므로 체크박스 상태 반영이 실패했습니다.
화살표 함수에서 event.target을 사용해 DOM 요소를 참조하면 문제를 해결할 수 있습니다.
const AllCheck = (event) => {
for (let i = 0; i < $AllCheckBox.length; i++) {
$AllCheckBox[i].checked = event.target.checked;
console.log(this);
}
}
$checkAll.addEventListener("change", AllCheck);
JavaScript에서 this는 함수가 호출되거나 정의되는 방식에 따라 동적으로 결정되는 컨텍스트를 가리킵니다.
function sayName() {
console.log(this.name);
}
sayName(); // '' (window.name)
const obj = {
name: "lee",
say() {
console.log(this.name); // 'lee'
}
};
obj.say(); // 'lee'
const x = obj.say;
x(); // '' (window.name, 독립 호출)
const obj = {
name: "lee",
say2: () => {
console.log(this.name); // '' (window.name)
}
};
obj.say2(); // '' (렉시컬 스코프: window)
function Human(name) {
this.name = name;
}
const person = new Human("lee");
console.log(person.name); // 'lee'
header.addEventListener("click", function () {
console.log(this); // header (DOM 요소)
});
header.addEventListener("click", () => {
console.log(this); // window (렉시컬 스코프)
});
function sayName() {
console.log(this.name);
}
sayName.call({ name: "lee" }); // 'lee'
sayName.apply({ name: "lee" }); // 'lee'
const boundSay = sayName.bind({ name: "lee" });
boundSay(); // 'lee'
this는 다음 상황에서 기본값(전역 객체 또는 undefined)과 다르게 설정됩니다:
메서드 호출: obj.method() → this는 obj.
생성자 호출: new Constructor() → this는 새 객체.
이벤트 리스너: 일반 함수 → this는 DOM 요소.
call, apply, bind: this는 지정된 객체.
화살표 함수: this는 정의 시점의 렉시컬 스코프의 this.
const obj = {
name : "lee",
say () {
console.log(this.name); // 'lee'
function say2 () {
console.log(this.name); // '', 호출할 때 this를 바꿔주는 행위를 안함
}
const say3 = () => {
console.log(this.name) // 'lee', 화살표 함수는 부모함수의 this를 물려 받는다.
}
say2();
say3();
},
}
const say = obj.say;
obj.say();
say(); // 전부 this가 window에 바인딩, ''만 출력
header.addEventListener('click', () => {
console.log(this); // header html값
})
// 변수.이벤트 리스너의 this는 무조건 변수의 html 값
일반 함수: 호출 방식에 따라 this 결정 (전역 객체, 객체, DOM 요소 등).
화살표 함수: 정의 시점의 렉시컬 스코프의 this 고정.
call, apply, bind: this를 명시적으로 설정.