[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 연산자와 함께 호출할 수 없다.
Leave a comment