-
Notifications
You must be signed in to change notification settings - Fork 13
Class vs Factory function: exploring the way forward
ECMAScript 2015(일명 ES6)는 클래스 구문과 함께 제공되므로 이제 우리는 객체를 만들기 위해 두 가지 경쟁 패턴을 가지고 있습니다. 이를 비교하기 위해 클래스와 동일한 객체 정의(TodoModel)를 만든 다음 Factory function로 만들어 봅니다.
class TodoModel {
constructor(){
this.todos = [];
this.lastChange = null;
}
addToPrivateList(){
console.log("addToPrivateList");
}
add() { console.log("add"); }
reload(){}
}
TodoModel as a Factory Function
function TodoModel(){
var todos = [];
var lastChange = null;
function addToPrivateList(){
console.log("addToPrivateList");
}
function add() { console.log("add"); }
function reload(){}
return Object.freeze({
add,
reload
});
}
우리가 알아차릴 수 있는 것은 클래스 객체의 모든 구성원, fields 그리고 methods가 public이라는 것입니다.
var todoModel = new TodoModel();
console.log(todoModel.todos); //[]
console.log(todoModel.lastChange) //null
todoModel.addToPrivateList(); //addToPrivateList
캡슐화의 부족은 보안 문제를 발생시킬 가능성이 있습니다. Developer Console에서 직접 수정할 수 있는 전역 객체의 예를 들어 보십시오. Factory function를 사용할 때 우리가 공개하는 메소드만 public이 되고, 나머지는 캡슐화됩니다.
var todoModel = TodoModel();
console.log(todoModel.todos); //undefined
console.log(todoModel.lastChange) //undefined
todoModel.addToPrivateList(); //taskModel.addToPrivateList
is not a function
this
가 context 잃는 문제는 클래스를 사용할때 여전히 존재합니다. 예를 들어 this
는 중첩된 함수에서 context를 잃어 버리는 것입니다.
코딩 과정에서 짜증나는 것은 아니지만 버그의 지속적인 원천이기도 합니다.
class TodoModel {
constructor(){
this.todos = [];
}
reload(){
setTimeout(function log() {
console.log(this.todos); //undefined
}, 0);
}
}
todoModel.reload(); //undefined
또는 this
는 메소드가 DOM 이벤트와 같이 콜백으로 사용할 경우 context를 잃어 버리는 것입니다.
$("#btn").click(todoModel.reload); //undefined
Factory function를 사용할 때 이와 같은 문제는 전혀 없습니다.
function TodoModel(){
var todos = [];
function reload(){
setTimeout(function log() {
console.log(todos); //[]
}, 0);
}
}
todoModel.reload(); //[]
$("#btn").click(todoModel.reload); //[]
Arrow function는 부분적으로 클래스의 context 문제를 해결하지만 동시에 새로운 문제를 만듭니다.
-
this
는 더 이상 중첩 된 함수에서 context를 잃지 않습니다. - 메서드가 콜백으로 사용될 때
this
는 context를 잃어 버립니다. - Arrow function는 익명 함수의 사용을 촉진합니다.
Arrow function을 사용하여 TodoModel을 리팩토링했습니다. Arrow function으로 리팩토링하는 과정에서 우리는 가독성을 위해 매우 중요한 함수 이름 인 loose를 사용할 수 있다는 점에 유의해야합니다. 예를 보십시오:
//using function name to express intent
setTimeout(function renderTodosForReview() {
/* code */
}, 0);
//versus using an anonymous function
setTimeout(() => {
/* code */
}, 0);
Discover Functional JavaScript는 BookAuthority가 개발 한 최고의 새로운 Functional Programming eBook 중 하나입니다!
일부 의역이 들어간 경우도 있으므로 해당 원문의 내용과 조금 다를 수 있습니다.
문제가 될 소지가 있다거나 혹은 수정이 필요한 사항이 있다면 있다면 issues 보내주세요.
기술문서
- 호출스택
- 원시자료형
- 값타입과 참조타입
- 명시적 변환, 암시적 변환, Nominal, 구조화, 덕 타이핑
- == vs === vs typeof
- 함수 범위, 블록 범위, 렉시컬(lexical) 범위
- 식(expression) vs 문(statement)
- IIFF, Modules, Namespaces
- 메세지큐와 이벤트루프
- setTimeout, setInterval, requestAnimationFrame
- 자바스크립트 엔진
- 비트 연산자, 형식화 배열, 버퍼(배열)
- DOM과 Layout Trees
- 팩토리와 클래스
- this, call, apply, bind
- new, 생성자, instanceof, 인스턴스
- 프로토타입의 상속과 체인
- Object.create와 Object.assign
- map, reduce, filter
- 순수함수, 부수효과, 상태변이
- Closure
- 고차함수
- 재귀
- 컬렉션과 생성기
- Promise
- async, await
- 자료구조
- 함수 성능과 빅 오 표기법
- 알고리즘
- 상속, 다형성, 코드의 재사용성
- 설계패턴
- 부분 어플리케이션, 커링, Compose, Pipe
- 클린코드