Using class in JS?
- ES6에 추가된 class 관련 글들을 찾아보면 class의 사용을 권장하지 않는 글들이 많다.
-
자바와 C++을 사용했던 많은 개발자들이 자바스크립트로 넘어오면서 자바스크립트에서도 oop를 따라하려는 시도로 class개념이 es6에 도입됨. 그러나…
-
자바스크립트의 class는 생성자 함수와 프로토타입 상속의 synthetic sugar일 뿐이다.
-
자바스크립트의 프로토타입 객체를 수정해야 한다.
-
더글라스 크락포드에 따르면 es6에서 추가된 class는 개발자들을 class를 사용하는 모델에서 벗어나지 못하게 만듦으로써 es6에 있어 최악의 업데이트라고 했다. (https://vimeo.com/97419177, 20:00)
-
class 기반인 객체지향 언어는 클래스의 상속 정보를 이용해 상속 구조 모습을 가진 새로운 객체의 틀을 뽑아내는 반면에 프로토타입을 통한 상속 구조는 존재하는 객체끼리 연결을 동적으로 표현한다. 즉 상속 받은 객체의 내용을 동적으로 추가, 삭제할 수 있다.
-
자바스크립트는 this는 함수가 어디서 정의되느냐가 아니라 어떻게 호출되는지에 따라 값이 달라진다.
function Person(name) {
this.name = name;
}
Person.prototype.talk = function () {
console.log(`${this.name} says hello`);
};
// 여기서 알아두어야 할 점은 talk 함수가 Person class의 캡슐화된 메소드가 아니라
// 객체 Person이 상속받은 함수라는것.
const Grey = new Person("Grey");
const mockDomObj = {};
mockDomObj.onClick = Grey.talk;
mockDomObj.onClick(); // this.name -> undefined!
// 예시에서 mockDomobj.onClick에서 this.name을 호출하게 되면 mockDomObj에서
// name이라는 프로퍼티를 찾는다.
mockDomObj.name = "button";
mockDomObj.onClick(); // this.name -> 'button'
- 위의 예시처럼 자바스크립트의 class는 캡슐화가 가능한 다른 class-based 언어와 다르게 동작하며 자바스크립트를 처음 접해본 사람들을 이해하기 어렵게 만든다.
- 자바스크립트에서 class 보다는 객체를 반환하는 팩토리 함수를 사용해보는것도 좋다.
const PersonFactory = (name) => ({
talk() {
console.log(`${name} says Hello`)
};
});
- 팩토리 함수를 사용한다면 클로저를 활용하기 때문에 bind나 this를 사용하지 않아도 된다.
const Grey = PersonFactory("Grey");
const mockDomObj = {};
mockDomObj.onClick = Grey.talk;
mockDomObj.onClick(); // -> Grey says Hello
- 팩토리 함수를 사용하니 name 프로퍼티를 private으로 만들었다.
- 만약에 프로퍼티를 공유하고 싶다면 extends와 같은 키워드가 필요하지 않다. 대신 팩토리 함수에서 생성되는 객체를 변환하면 된다. 예를들어 Object.assign을 사용해서 PersonFactory 함수가 Mammal 프로퍼티를 공유하게 할 수도 있다.
const Mammal = {
isVertebrae: true,
};
const PersonMammalFactory = (name) =>
Object.assign({}, Mammal, PersonFactory(name));