📌 참고 목록
- 모던 자바스크립트 Deep Dive pg. 444 클래스 필드와 화살표 함수
- 제로초 ES2021 자바스크립트 강좌 10-5. 클래스 사용하기(팩토리, 생성자)
- 제로초 ES2021 자바스크립트 강좌 10-6. 클래스로 재구성하기
- 제로초 ES2021 자바스크립트 강좌 10-7. 화살표 함수와 this
객체를 생성하기 위한 템플릿(서식)
이전에 객체를 찍어냈던 방식은 '함수'의 형태
객체를 반환하는 공장(factory) 함수
function createPerson(name, age) {
return { name, age };
}
const person1 = createPerson("다은", 25);
const person2 = createPerson("주현", 24);
생성자 함수
// this는 본래 window지만 함수 앞에 new를 붙이면 this가 자기자신(반환되는 새로운 객체)이 됨
function Person(name, age) {
this.name = name;
this.age = age;
}
const personA = new Person("다은", 25);
const personB = new Person("주현", 24);
클래스의 등장
// 클래스의 경우 new를 쓰지 않으면 애초에 에러가 발생함
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
const person1 = new Person("다은", 25);
const person2 = new Person("주현", 24);
화살표 함수는 함수 자체의 this 바인딩을 갖지 않음
상위 스코프의 this를 그대로 참조 (렉시컬 스코프와 같이 함수가 정의된 위치에 의해 this가 결정)
화살표 함수가 중첩되어 있을 경우, 스코프 체인 상 가장 가까운 상위 함수 중 화살표 함수가 아닌 함수의 this를 참조
call, apply, bind를 활용하여 this 값을 직접 지정(변경)할 수 없음
function a() {
console.log(this);
}
a.bind(document)(); // document
function b = () => {
console.log(this);
}
b.bind(document)(); // window
메서드를 화살표 함수로 정의하는 것은 피하는 것이 좋음 (this가 메서드를 호출한 객체가 아닌 상위 스코프인 전역 객체를 가리킴)
cf. 일반 함수의 this 바인딩
strict mode가 적용된 일반 함수 내부의 this → undefined
중첩/콜백 함수 내부의 this 또한 → 전역 객체 window
var value = 1;
const obj = {
value: 100;
foo() {
// this 바인딩(obj)을 변수 that에 할당 (_this, self와 같은 변수명도 활용 가능)
const that = this;
setTimeout(function() {
console.log(this.value); // 1
console.log(that.value); // 100
}, 100);
}
}
obj.foo();
class Game {
constructor() {
this.start();
}
start() {
console.log(this); // Game 객체
const that = this;
$gameForm.addEventListener("submit", function (event) {
console.log(this); // gameForm 폼
// this.changeScreen("battle"); // ERROR!
that.changeScreen("battle"); // 안팎의 this가 다른 문제를 해결
});
}
changeScreen(screen) { ... }
}
class App {
constructor() {
this.$button = document.querySelector(".btn");
this.count = 0;
// 이벤트 핸들러 내부의 this는 DOM 요소 (this.$button)을 가리킴
// this.$button.onclick = this.increase;
// 만약 increase 함수가 화살표 함수가 아니라면 bind 메서드를 사용해야 함
$button.onclick = this.increase.bind(this);
}
// 인스턴스 메서드
// 화살표 함수가 아닐 경우
increase() {...}
}
class Game {
constructor() {
this.start();
}
start() {
console.log(this);
$gameForm.addEventListener("submit", (event) => {
// 화살표 함수를 쓰게 될 경우 화살표 함수 바깥의 this가 그대로 이 안의 this로 들어오게 됨
});
changeScreen(screen) { ... }
}
class App {
constructor() {
this.$button = document.querySelector(".btn");
this.count = 0;
this.$button.onclick = this.increase;
}
// 인스턴스 메서드
// 화살표 함수 내부의 this는 언제나 상위 컨텍스트의 this를 가리킴
increase = () => this.$button.textContent = ++this.count;
}