Class vs Factory function: exploring the way forward - Lee-hyuna/33-js-concepts-kr GitHub Wiki
Class vs Factory function: ์์ผ๋ก์ ๊ธธ์ ๋ชจ์ํ๋ค.
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
});
}
Encapsulation (์บก์ํ)
์ฐ๋ฆฌ๊ฐ ์์์ฐจ๋ฆด ์ ์๋ ๊ฒ์ ํด๋์ค ๊ฐ์ฒด์ ๋ชจ๋ ๊ตฌ์ฑ์, 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
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); //[]
this ๊ทธ๋ฆฌ๊ณ arrow function
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 ์ค ํ๋์ ๋๋ค!