자바스크립트 함수의 this 바인딩
참고한 글 (this 바인딩에 대해 잘 정리되어 있는 글)
알쏭달쏭 자바스크립트 this 바인딩 https://seungtaek-overflow.tistory.com/21
this 바인딩 이해하기 https://velog.io/@defaultkyle/js-this-1
자바스크립트의 this 바인딩 이해하기 https://f-lab.kr/insight/understanding-javascript-this-binding-20240525
0. this 바인딩 직접 실험해보기
ㄴ 폴더
ㄴ script.js
ㄴ index.html
이렇게 파일 만들고 아래 코드 붙여넣기
1. script.js
class Car {
run() {
console.log(this);
setTimeout(function () {
console.log(this); // this = Window
}, 1000);
}
stop() {
console.log(this);
setTimeout(() => {
console.log(this); // this = Car {}
}, 1000);
}
}
const myCar = new Car();
myCar.run(); // this = Car {}
2. index.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>JS this 테스트</title>
</head>
<body>
<h1>this 테스트</h1>
<script src="script.js"></script>
</body>
</html>
3. vscode extension - live server 설치
4. index.html 우클릭 > Open with Live Server
1. 전역 컨텍스트에서 호출하는 this
console.log(this);
아무것도 없이 그냥 냅다 this를 부르는 경우
1) 브라우저 환경: this는 window를 가리킴
-> window 반환
2) Node.js 환경: this는 global이 아니라 module.exports를 가리킴
-> {} 빈 객체 반환
이건 그냥 뻘소린데 왜 맨날 예시 함수가 foo인지 궁금해서 gpt한테 물어봄
근데 진짜로 유래가 있는 게 웃겼음
foo는 군대 무전 용어에서 시작된 단어
FUBAR (F***ed Up Beyond All Recognition, 완전 춋됐다는 뜻) ->이걸 줄여서 FOO라고 했대요
근데 1950년대 프로그래밍 교재에서 예제로 이걸 갖다 쓰면서 개발자들이 계속 쓰게 됐대요
찾아보니까 진짜 이런 식으로 유래 말하는 것도 있던데...뭐 믿거나 말거나
2. 클래스의 메서드에서 호출하는 this
* 메서드: 클래스 안에서 정의된 함수
난 foo가 싫어서 gpt한테 예제 만들어달라고 할래요
class Car {
run() {
console.log(this);
}
}
const myCar = new Car();
myCar.run(); // this = myCar
myCar.run();을 실행하면, Car가 run()을 호출한 "객체"가 된다
JavaScript에서 객체의 메서드를 호출할 때 this는 해당 객체를 가리킨다.
run()은 Car 객체를 가리킨다.
그래서 this는 Car {}가 된다
3. 클래스의 메서드 안에서 setTimeout으로 일반 함수(function)를 호출하면?
class Car {
run() {
console.log(this);
setTimeout(function() {
console.log(this); // this = window
},1000);
}
}
const myCar = new Car();
myCar.run(); // this = Car {}
myCar.run{)을 실행했으니까 일단 메서드가 호출됨
run 바로 아래 있는 console.log(this);가 실행될 때는
위에서 설명했듯이 this는 본인을 호출한 객체 Car {}를 가지고 있음
setTimeout으로 감싸진 함수는 1초 후에 실행됨
setTimeout()는 window 객체의 메서드임. window.setTimeout()이 호출되는 것과 마찬가지임.
일반 함수(function)의 this는 "어떤 객체에서 호출했냐"에 따라 값이 달라짐.
setTimeout() 메서드는 window를 객체로 가지므로, 여기에서는 일반 함수를 "window" 객체에서 호출한 것.
일반 함수의 this는 window가 됨
4. 클래스의 메서드 안에 setTimeout으로 화살표 함수(=>)를 호출하면?
class Car {
run() {
console.log(this);
setTimeout(() => {
console.log(this); // this = Car {}
},1000);
}
}
const myCar = new Car();
myCar.run(); // this = Car {}
일반 함수는 "어떤 객체에서 호출했느나"에 따라 this 값이 달라짐
그런데 화살표 함수는 this를 새로 만들지 않고, '선언된 곳'의 상위 스코프의 this를 그대로 유지함
//엄연히 말하면 this를 상위 스코프에서 상속받는 게 아니라 "this를 새로 만들지 않는다"가 맞다고 함
setTimeout(()=>{ .. }) 안의 this는 run()의 this를 그대로 유지함.
그래서 myCar.run()을 호출했을 때, run()의 this인 Car {}를 그대로 유지해서
setTimeout 내부의 화살표 함수 내부의 this는 Car {}가 됨
* 그냥 혼자서 들었던 의문
화살표 함수가 단순히 상위 스코프의 this를 상속한다면, setTimeout의 객체인 window가 this가 되는거 아닌가?
근데 이건 잘못된 생각이고, 화살표 함수는 "선언된 곳"의 상위 스코프 this를 가져오는 것.
그래서 '선언된 곳'인 run()의 this를 가져옴
5. addEventListner 안에서 this를 호출하면?
document.addEventListener("click", function () {
console.log(this);
});
addEventListner는 this의 이벤트가 발생한 요소를 가리킴
클릭한 요소(document, button, div 등)가 this가 된다
작성: 25.02.20. 오전 12:58
'개발자 강화 > 프론트엔드' 카테고리의 다른 글
[개발][BFF 도전기] 부동산 공공데이터 API 뜯어보고 BFF API 설계하기 (0) | 2025.02.20 |
---|---|
[개발][BFF 도전기] Docker 이미지 빌드 - ECR로 push - EC2 pull해서 실행 (0) | 2025.02.18 |
[개발][BFF 도전기] Fastify 서버 - 폴더 구조화 (0) | 2025.02.18 |
[개발][BFF 도전기] Next.js 구축, Fastify에 Swagger 안 붙는 문제 해결하기 (1) | 2025.02.16 |
🌟[매일메일] 이벤트 전파(Event Propagation)란? (FE.250106) (0) | 2025.02.14 |