JavaScript에서 컨텍스트 손실
함수 안에 함수가 있는 상황을 생각해 봅시다.
바깥 함수는 parent라고 하고,
안쪽 함수는 child라고 부르겠습니다:
function parent() {
function child() {
}
}
이전 수업들에서 배웠듯이, 바깥 함수에서 어떤 변수를 설정하면 안쪽 함수에서도 접근할 수 있습니다:
function parent() {
let str = 'abcde';
function child() {
console.log(str); // 'abcde'를 출력합니다
}
child(); // 내부 함수를 호출합니다
}
parent(); // 외부 함수를 호출합니다
그러나 주의할 점이 있습니다: 내부 함수는
외부 함수의 모든 변수에 접근할 수 있지만,
this에는 접근하지 못합니다. 즉:
외부 함수가 어떤 DOM 요소에 연결되어 있다면,
그 안의 this는 그 요소를 가리키지만,
내부 함수의 this는 그렇지 않습니다!
그렇다면 내부 함수의 this는
무엇을 가리킬까요? 답: 엄격 모드에서는
undefined와 같습니다,
함수가 아무것에도 연결되어 있지 않기 때문입니다.
실제로 확인해 봅시다. 다음과 같은 입력 필드가 있습니다:
<input id="elem" value="text">
이 입력 필드에 parent 함수를 연결하고,
입력 필드가 포커스를 잃을 때 호출되도록 하겠습니다:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
// 포커스를 잃을 때 호출됩니다:
function parent() {
// 여기에 어떤 코드가 있습니다
function child() {
// 여기에 어떤 코드가 있습니다
}
child(); // 자식 함수를 호출합니다
}
두 군데에서 this의 내용을 콘솔에 출력해 보겠습니다:
parent 함수 내부와 child 함수 내부입니다:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this); // 입력 필드에 대한 참조를 출력합니다
function child() {
console.log(this); // undefined를 출력합니다
}
child();
}
이 코드를 실행하고, 입력 필드의 포커스를 잃게 한 후
콘솔을 확인해 보세요 - 첫 번째 console.log는
입력 필드에 대한 참조를 출력하고, 두 번째는 단순히 undefined를
출력할 것입니다.
이렇게 this가 예상과 다르게 우리가 원하는 대상을
가리키지 않는 상황을 컨텍스트 손실이라고 합니다.
이제 두 함수 모두에서 입력 필드의 value를
출력한다고 가정해 봅시다. 주석으로 표시된 코드 줄이
무엇을 출력할지 결정하세요:
"use strict";
let elem = document.querySelector('#elem');
elem.addEventListener('blur', parent);
function parent() {
console.log(this.value); // 무엇을 출력할까요?
function child() {
console.log(this.value); // 무엇을 출력할까요?
}
child();
}