티스토리 뷰

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)

결론

다음에 자바스크립트 작성할 일이 있을때 팩토리 패턴 도입을 고려해보도록 하자. 이 글만 봐서는 팩토리 패턴이 클래스에 비해 가진 장점이 더 많아보인다.

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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 31
글 보관함