다른 함수를 매개 변수로 사용하여 데이터를 처리하거나 함수를 반환하는 함수
동일한 인자를 넣었을 때 항상 동일한 리턴값을 반환하고 선언시점이나 외부에 영향을 받지 않는 함수
let c = 10;
function add2(a, b) {
return a + b + c;
}
console.log( add2(10, 2) ); // 22
c = 20;
console.log( add2(10, 2) ); // 32
"어떻게" 수행하는지에 초점
12번 테이블 자리가 비어있으니 나는 저 자리로 똑바로 걸어가 앉을 것입니다.
let inputTxt = 'This is a computer';
let result = "";
for(let i=0; i<inputTxt.length; i++) {
result += inputTxt[i] === " " ? "-" : string[i]
}
console.log(result); // This-is-a-computer
"무엇을" 원하는지에 초점
네 명 앉을자리를 부탁해요
const inputTxt = 'This is a computer';
const blankToHyphen = inputTxt.replace(/ /g, '-');
console.log(blankToHyphen); // This-is-a-computer
❗️ 선언형 > 명령형
성공적인 프로그래밍을 위해 부수효과를 미워하고 조합성을 강조하는 프로그래밍 패러다임
- 순수함수를 통해 부수효과를 미워하고 조합성을 강조해 모듈화 수준을 높혀 생산성을 높인다.
// 3. 30세 미만인 users를 거른다.
let temp_users = [];
for (let i = 0; i < users.length; i++) {
if (users[i].age < 30) {
temp_users.push(users[i]);
}
}
console.log(temp_users);
const over_30_cond = user => user.age >= 30
const over_30_users = _filter(users, over_30_cond);
console.log(over_30);
- 반복문 대신에 map과 filter, reduce, all, any, find 등을 사용
- 명령형으로 작성하지 말고 선언형으로 작성
- 파이프라인을 사용
다중 인수를 갖는 함수를 단일 인수를 갖는 함수들의 함수열로 바꾸는 것을 말한다.
let sum = function (x, y) {
return x + y;
};
console.log(sum(5, 7)); // 12
let sum = x => y => x+y;
let sum5 = sum(5);
let sum12 = sum5(7);
console.log(sum12, sum(5)(7)); // 12 12
let printInfo = function(group, name){
console.log(group + ', ' + name);
};
printInfo('dev-momo', 'haegul'); // dev-momo, haegul
printInfo('dev-momo', 'jiwon'); // dev-momo, jiwon
printInfo('dev-momo', 'sungcheon'); // dev-momo, sungcheon
// currying
let printInfo = group => name => console.log(group + ', ' + name);
let momoGroup = printInfo('dev-momo');
momoGroup('haegul'); // dev-momo, haegul
momoGroup('jiwon'); // dev-momo, jiwon
momoGroup('sungcheon'); // dev-momo, sungcheon
컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위, 즉 "객체"들의 모임으로 파악하고자 하는 것
문제 해결을 위한 데이터를 모아 놓은 데이터형을 사용함으로써 응집력을 강화하고, 클래스간에 독립적으로 디자인함으로써 결합력을 약하게 할 수 있다.
🏃 "동사" 중심 - (무엇을 원하느냐, 어떤 것을 하느냐 - 함수기준)
moveLeft(penguin);
moveLeft(dog);
moveLeft({x: -5, y: 2})
swim(penguin, fast)
🐧 "명사" 중심 - (데이터/객체 기준)
penguin.moveLeft();
penguin.swim();
dog.moveLeft({x: -5, y: 2});
dog.run();
// 함수형
function TodoList(data, queryId) {
this.todos = data
this.render = function () {
document.querySelector(queryId).innerHTML =
this.todos
.map(todo => todo.isCompleted ? `<li><s>${todo.text}</s></li>` :
`<li>${todo.text}</li>`)
.join('\n')
}
this.setState = function (nextData) {
this.todos = nextData
this.render()
}
}
const todoList = new TodoList(data, '#todo-list');
todoList.render();
todoList.setState([{
text: '새롭게 할 일',
isCompleted: false
}]);
// 클래스형
class TodoList {
constructor(data, queryId) {
this.todos = data
this.queryId = queryId
}
render() {
document.querySelector(
this.queryId
).innerHTML = this.todos
.map((todo) =>
todo.isCompleted ?
`<li><s>${todo.text}</s></li>` :
`<li>${todo.text}</li>`
)
.join('\n')
}
setState(nextData) {
this.todos = nextData
this.render()
}
}
const todoList = new TodoList(data, '#todo-list')
todoList.render()
todoList.setState([{
text: '새롭게 할 일',
isCompleted: false,
}, ])
// 함수형
import React from 'react';
function App() {
const name = '리액트';
return <div>{name}</div>;
}
export default App;
// 클래스형
import React, { Component } from 'react';
class App extends Component {
render() {
const name = '리액트';
return <div>{name}</div>;
}
}
export default App;
❓ 왜 클래스형에서 함수형으로 넘어갔을까
(현재 공식문서에서 함수형 컴포넌트와 훅 사용 권장 중)
Hook를 사용하면 컴포넌트로 부터 상태 관련 로직을 추상화 할 수 있다. 이것은 독립적인 테스트와 재사용이 가능하다.
Hook은 계층 변화 없이 상태 관련 로직을 재 사용할 수 있어 많은 컴포넌트들이 공유하기 쉬워지는 역할을 한다.
Class 컴포넌트보다 Functional 컴포넌트가 가독성이 뛰어나다
Class 컴포넌트가 최적화를 더 느린 경로로 되돌리는 의도하지 않은 패턴을 장려할 수 있다
Class는 잘 축소되지 않고, 핫 리로딩을 깨지기 쉽고 신뢰할 수 없게 만든다
클래스 컴포넌트의 문제점
클래스 컴포넌트에서 follow 클릭 후 3초가 지나기 이전에 다른 유저의 페이지를 누르면 이전 유저가 아닌 두번째로 선택한 유저에대한 알림이 발생한다. 이는 클래스 컴포넌트는 props를 재사용 하기 때문이라고 한다.
가독성이 좋고 재사용성과 조합성이 높으며 에러 추적이 쉬운
함수형 프로그래밍
을 활용하자!