[JavaScript] 클래스와 화살표 함수

정다은·2022년 10월 16일
1
post-thumbnail

📌 참고 목록


클래스

  • 객체를 생성하기 위한 템플릿(서식)

  • 이전에 객체를 찍어냈던 방식은 '함수'의 형태

    • 객체를 반환하는 공장(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가 결정)

  • 화살표 함수가 중첩되어 있을 경우, 스코프 체인 상 가장 가까운 상위 함수 중 화살표 함수가 아닌 함수의 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


메서드 내부의 중첩/콜백 함수의 this 바인딩을 메서드의 this 바인딩과 일치시키기 위한 방법

  • 상위 스코프의 this를 변수에 저장해서 사용
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) { ... }
}
  • 또는 bind/apply/call 메서드 활용
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() {...}
}
  • 또는 화살표 함수 내부의 this → 상위 스코프의 this
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;
}
profile
벨로그에는 주로 알고리즘 문제를 풀고 기록합니다 ✍

0개의 댓글