티스토리 뷰
https://www.notion.so/simsimjae/14-2-vs-85e2889263ae4c2baa482e18971fb963
아래 글들은 검색엔진 노출을 위한 글입니다.
노션에서 확인하시면 이미지와 함께 정리된 글을 보실수 있습니다. 궁금하신점은 블로그 댓글이나 노션 코멘트를 이용해주세요(@comment)
제가 직접 만든 프로젝트입니다.
http://pickvs.com : 닥전닥후
클래스
class TodoModel { constructor(){ //멤버 변수 2개 정의(public) this.todos = []; this.lastChange = null; } //메소드 3개 정의 (public) addToPrivateList(){} add() {} reload(){} }
팩토리 패턴
function TodoModel(){ //Private 영역 var todos = []; var lastChange = null; function addToPrivateList(){} function add() {} function reload(){} //Private 영역 return Object.freeze({ add, //public reload //public }); }
Object.freeze → 인자로 넘겨진 객체와 그 객체의 프로토타입의 속성 변경을 금지시키는 메소드 → freeze된 인자 객체를 리턴함
클래스의 문제점1 - 캡슐화불가능
- 팩토리 메서드 패턴을 사용하면 Private영역과 Public영역을 구분해 줄 수 있다. → 내가 공개 하고 싶은 메소드만 선택적으로 공개 할 수 있다.(add, reload)
- 클래스를 사용해서 객체를 만들면 private변수와 public변수를 구분할 수 없다. → 캡슐화가 불가능하다.
클래스의 문제점2 - this, context소실문제
class TodoModel { constructor(){ this.**todos** = []; } reload(){ setTimeout(function log() { console.log(**this.todos**); }, 0); } } todoModel.reload(); // undefined 출력, context 소실
-
reload메소드를 호출하면 setTimeout이 실행되고 첫번쨰 콜백인 log함수가 호출된다. 하지만 이때, log 함수 내부에서의 this는 window객체를 가리킨다. reload내부에서의 this는 TodoModel 객체를 가리키겠지만, 콜백함수에서는 this가 TodoModel로 유지 되지 않는다. → context가 소실되었다고 표현한다
-
반면에 다음과 같이 팩토리 패턴에서는 스코프 체인에 의한 변수 참조에 의해서 상위 함수에 선언한 변수가 하위 함수들에도 유지 된다.
function TodoModel(){ var todos = [];
function reload(){ setTimeout(function log() { console.log(**todos**); //[] }, 0); }} todoModel.reload(); //[] $("#btn").click(todoModel.reload); //[],
-
심지어, 위와 같이 버튼 클릭에 의한 이벤트 핸들러에서도 컨텍스트가 유지된다.
물론 클래스 키워드에서도 이런 문제들을 해결할 수 있다.
arrow function 활용
- 화살표 함수를 사용하면 상위 컨텍스트의 this가 하위 컨텍스트에도 전달된다.
- 이 특성을 활용하면 컨텍스트 소실 문제가 발생하는걸 막을 수 있다.
- 하지만 여전히 다음과 같은 문제들이 있다.
1. 콜백에서의 컨텍스트 소실
function reload(){ setTimeout( () => console.log(this.**todos**), 0); } $("#btn").click(todoModel.reload); // 이렇게 호출 했을때, this는 TodoModel 객체가 아니라, window객체이다. // undefined 출력됨.
2. 익명함수의 사용을 유발한다.
setTimeout(function renderTodosForReview() { /* code */ }, 0); // 함수의 의도를 표현하기 위해 함수의 이름을 적어주는것이 좋다. setTimeout(() => { /* code */ }, 0); // 반면에 위와 같이 화살표 함수를 사용하게 되면 익명함수를 쓸 수 밖에 없다. (함수 의도 파악 X)
결론
다음에 자바스크립트 작성할 일이 있을때 팩토리 패턴 도입을 고려해보도록 하자. 이 글만 봐서는 팩토리 패턴이 클래스에 비해 가진 장점이 더 많아보인다.
'Javascript' 카테고리의 다른 글
#20-1 참조 투명성 예시 (referential transparency) (0) | 2019.09.26 |
---|---|
#20 순수함수와 사이드 이펙트 (0) | 2019.09.26 |
#14 팩토리 패턴과 클래스 (0) | 2019.09.25 |
#13 자바스크립트 DOM 이해하기 (0) | 2019.09.25 |
#12 자바스크립트 비트연산 활용하기 (0) | 2019.09.25 |
- Total
- Today
- Yesterday
- Babel
- design system
- server side rendering
- es6
- reactdom
- react
- mobx
- hydrate
- storybook
- Polyfill
- rendering scope
- webpack
- async
- props
- await
- useEffect
- reducer
- react hooks
- promise
- state
- useRef
- reflow
- typescript
- type alias
- return type
- atomic design
- Next.js
- computed
- Action
- javascript
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |