[240404] 24장 클래스 (1)

24장 클래스 (1)

  • 프로토타입 기반 객체 지향 언어는 클래스가 필요없는 객체짛향 프로그래밍 언어다.
  • 아래와 같이 프로토타입을 통해 객체지향 언어의 상속 구현 가능
// ES5 생성자 함수
var Person = (function () {
	// 생성자 함수
	function Person(name) {
		this.name = name;
	}

	// 프로토타입 메서드
	Person.prototype.sayHi = function () {
		console.log('Hi ! My name is' + this.name);
	};
	
	// 생성자 함수 반환
	return Person;
	
	}());
	
	var me = new Person('Lee');
	me.sayHi(); // Hi ! My name is lee
  • ES6 에 도입된 클래스는 클래스 기반 객체지향 프로그래밍 언어와 흡사한 객체 생성 메커니즘 제시
  • 하지만 클래스는 사실 함수이며 프로토타입 기반 패턴을 클래스 기반 패턴처럼 사용할 수 있도록 하는 문법적 설탕이라고 볼 수 있음
  • 완전 동일하지는 않고, 생성자와 차이점도 있다.
    • 클래스는 new 연산자 필수, 생성자는 일반 함수로 호출
    • 클래스는 상속 지원하는 extends super 키워드 제공
    • 클래스는 호이스팅이 발생하지 않는 것처럼 동작하지만 동작한다.
    • 클래스 내의 모든 코드에는 암묵적으로 strict mode가 지정되어 실행된다.
    • 클래스의 constructor, 프로토타입 메서드, 정적 메서드는 모두 프로퍼티 어트리뷰트 [[Enumerable]] 값이 false다. 즉 열거되지 않음

클래스 정의

  • 파스칼 케이스
  • 이름을 갖지 않을 수도 있음
  • 표현식으로 정의할 수 있다 → 일급 객체
    • 무명의 리터럴로 생성 가능 런타임에 생성 가능
    • 변수나 자료구조에 저장 가능
    • 함수의 매개변수에 전달 가능
    • 함수의 반환 값으로 사용 가능
  • 클래스는 함수다.
  • 몸체에는 0개 이상의 메서드만 정의 가능
    • constructor(생성자), 프로토타입 메서드, 정적 메서드
// 클래스 선언문 
class Person {
	// 생성자
	constructor(name) {
		// 인스턴스 생성 및 초기화
		this.name = name; // name 프로퍼티는 public 하다. 
	}
	
	// 프로토타입 메서드
	sayHi () {
		console.log(`Hi ! My name is ${this.name}`);
	}
	
	// 정적 메서드
	static sayHello() [
		console.log('Hello!');
	}
}

// 인스턴스 생성
const me = new Person('Lee');

// 인스턴스의 프로퍼티 참조
console.log(me.name); // Lee
me.sayHi(); // Hi! My name is Lee
// 정적 메서드 호출
Person.sayHello(); // Hello! 

클래스 호이스팅

// 클래스 선언문
class Person {} 

console.log(typeof Person); // function
  • 함수 선언문과 같이 런타임 이전에 평가 되어 함수 객체 생성
  • 생성된 함수 객체는 constructor 임 (생성자 함수로서 호출)
    • 함수 객체 시점에 프로토타입도 더불어 생성
  • 단, 정의 이전에 참조할 수 없다. (호이스팅이 발생하지 않는 것처럼 보이나 그렇지 않음)
    • let const 처럼 TDZ에 빠짐

인스턴스 생성

  • new 연산자와 함께 호출되어 인스턴스 생성
  • new 연산자 없으면 타입 에러 발생

메서드

1. constructor

  • 인스턴스 생성하고 초기화하기 위한 특수한 메서드
  • 이름 변경 불가능
  • 클래스도 함수 객체 고유의 프로퍼티 갖고 있음, 스코프 체인 구성
  • prototype 프로퍼티가 가리키는 프로토타입 객체의 construct 프로퍼티는 클래스 자신을 가리키고 있고, 이는 생성자 함수라는 것을 의미
  • coustructor 는 메서드로 해석되는 것이 아니라 클래스가 평가되어 생성한 함수 객체 코드의 일부가 된다.
  • 2개 이상 포함하면 문법 에러
  • 생략 가능 → 빈 객체 생성
  • 반환문을 갖지 않아야함. new 연산자와 함께 클래스가 호출되면 암묵적으로 this, 인스턴스 반환하기 때문 (생성자 함수와 동일)
    • 원시값 반환하면 암묵적으로 무시함

2. 프로토타입 메서드

  • 클래스 몸체에서 정의한 메서드는 인스턴스의 프로토타입에 존재하는 프로토타입 메서드가 된다.
  • 인스턴스는 프로토타입 메서드를 상속받아 사용할 수 있다.

3. 정적 메서드

  • 인스턴스를 호출하지 않아도 사용 가능
  • 클래스에 바인딩 된다.
  • 인스턴스로 호출할 수 없다. 인스턴스의 프로토타입에 존재하지 않기 때문

4. 정적 메서드와 프로토타입 메서드의 차이

  • 자신이 속해 있는 프로토타입 체인이 다르다.
  • 정적 메서드는 클래스로 호출, 프로토타입 메서드는 인스턴스로 호출
  • 정적 메서드는 인스턴스 프로퍼티를 참조할 수 없지만, 프로토타입 메서드는 인스턴스 프로퍼티를 참조 가능
    • this 는 마침표 연산자 앞에 기술한 객체 바인딩
Math.max(1,2,3); // 3 
Number.isNaN(NaN); // true

5. 클래스에서 정의한 메서드의 특징

  • function 키워드를 생략한 메서드 축약 표현 사용
  • 객체 리터럴과는 다르게 클래스에 메서드를 정의할 때는 콤마가 필요없다.
  • 암묵적으로 strict mode 실행
  • [[Enumerable]] 값이 false 다.
  • 내부 메서드 [[ Construct ]] 를 갖지 않는 non-constructor 다. 따라서 new 연산자와 함께 호출할 수 없다.

Categories:

Updated:

Leave a comment