function returnvalue(unit){
return (parameter) => {
console.log(parameter * unit)
}
}
const returned = returnvalue(10)
returned(1230)
#2. 일급 함수
일급 함수는 함수를 변수에 할당 + 다른 함수에 인수(파라미터)로 전달 + 함수에서 값으로 반환할 수 있다.
자바스크립트에서 함수는 일급 객체의 조건을 만족하므로 일급 객체가 된다.
즉, 일급 함수는 함수를 일급 객체로 취급하는 것으로, 함수가 일급 객체라는 것은 함수를 객체와 동일하게 사용할 수 있다는 의미이다.
02. 순수 함수
순수 함수는 참조 투명성과 부수 효과가 없는(No-Side Effect) 특징을 가진다.
이때, 참조 투명성은 함수가 외부 상태에 의존하지 않는 것이고, No-Side Effect는 함수가 외부 상태를 변경하지 않는 다는 것을 의미한다. No-Side Effect는 참조 투명성에 포함관계를 가지는 것으로 볼 수 있으며, 이 두가지 특성은 아래에서 더 자세히 다루고자 한다.
순수 함수의 특성은 멀티 스레드 환경에서 스레드 안전성(Thread-Safe)을 보장하는데 매우 중요하다.
Thread-Safe 병렬적으로 실행되는 모든 함수가 서로에게 영향을 주지 않으며, 외부 상태를 변경하지 않는다. 하나의 작업을 여러 개로 나누어 수행한 뒤 합쳤을 때, 하나의 작업을 한 번에 수행했을 때와 같은 결과이어야 한다.
#1. 순수 함수 장점
테스트 가능 : 일정한 파라미터에 일정한 반환 값이 나오면 유닛테스트 용이
디버깅 가능 : 문제가 생기는 함수만 보면 문제가 해결
메모이제이션 가능 : 캐싱 가능
#2. 참조 투명성(Referential Transparency) 사례
var c = 3
function refer(a, b){
console.log(a + b + c)
}
refer(1, 2)
var c = 5
refer(1, 2)
위 예시는 참조 투명성을 위배한 사례 중 하나이다.
참조 투명성은 동일한 입력에 대해 항상 동일한 출력을 반환하는 함수의 특성을 말한다.
참조 투명성을 지키는 함수는 외부 상태에 의존하지 않으며, 함수 호출이 프로그램의 다른 부분에 영향을 미치지 않아야 한다.
위의 예시에서 함수 refer는 입력 값 a, b 외에 외부 변수 c에 의존하고 있다.
외부 변수 c는 함수 외부에서 선언되고 나중에 값이 변경된다. 이로 인해 refer 함수는 동일한 인자 1, 2를 전달받았음에도 c의 값이 변경되면서 서로 다른 결과를 반환한다. 첫 번째 refer(1, 2) 호출 시, c의 값은 3이므로 출력은 6, 두 번째 refer(1, 2) 호출 시, c의 값은 5로 변경되었으므로 출력은 8의 결과가 나온다. 이와 같은 이유로 위의 예시는 참조 투명성을 위배한 사례라 볼 수 있다.
#2. Side-Effect 사례
부수 효과(Side-Effect)는 함수가 외부 상태를 변경하거나, 외부에서 접근 가능한 상태에 영향을 미치는 경우를 말한다.
var object = {name: 'guswjd', age: 25}
function sideEffect_type1(){
object.name = 'guswjd2'
}
sideEffect_type1()
console.log(object)
이 코드에서는 자바스크립트의 객체 object를 사용하여 함수 호출 시 부수 효과(Side Effect)가 발생하는 예시이다.
sideEffect_type1 함수는 Side-Effect를 일으킨다. 함수가 외부 변수 object를 직접 변경하기 때문에, 함수 호출 전후로 object의 상태가 달라지게 된다. 해당 코드를 실행하면 콘솔에 {name: 'guswjd2', age: 25}가 출력되는 결과를 볼 수 있다.
var object = {name: 'guswjd', age: 25}
function sideEffect_type2(object){
object.name = 'guswjd22'
}
sideEffect_type2(object)
console.log(object)
다음과 같이 파라미터를 통해 객체를 전달받아 그 객체의 속성을 변경하는 방식이다.
하지만 여전히 side-effect를 발생시키며, 반환값 없이 함수 내부에서 객체를 변경하는 방식은 여전히 명시적이지 않다.
즉, 함수의 호출자 입장에서는 함수가 객체를 어떻게 수정할지, 수정 여부를 명확하게 이해하기 어렵고, 코드의 예측 가능성을 떨어뜨리며, 디버깅을 어렵게 만들 수 있다.
var object = {name: 'guswjd', age: 25}
function sideEffect_type3(object){
var copied = object
copied.name = 'guswjd22'
return copied
}
var manipulated = sideEffect_type3(object)
console.log(manipulated)
console.log(object)
manipulated == object
앞선 코드들의 너무 명시적이지 않은 문제는 위와 같이 해결하였다.
하지만, 함수 내부에서 object를 copied에 할당했지만, 이는 객체를 복사한 것이 아닌 같은 객체를 가리키는 또 다른 변수를 만든 것일 뿐이어서 copied.name을 변경하면 object.name도 함게 변경되는 문제가 여전히 발생한다. 함수가 반환하는 copied와 원본 object는 동일한 객체이기 때문에 함수가 반환한 manipulated와 object는 똑같은 객체를 가리켜 manipulated == object는 true인 결과가 나오는 것이다.
이와 같은 문제들을 해결하기 위해서는 객체를 완전히 복사해야 한다. 즉, 새 객체를 만들어 반환하고, 원본 객체는 변경되지 않아야 한다.
#3. Side-Effect 사례 해결 방법 : Immutability 불변성
Side-Effect를 방지하기 위해서는 불변성을 유지하는 것이 중요하다.
불변성은 함수나 코드가 외부 상태를 변경하지 않도록 보장하는 방법을 말한다.
자바스크립트에서는 객체를 불변으로 유지하기 위해 Object.freeze()를 사용하거나 const로 선언하여 재할당을 막을 수 있다.
var object = {name: 'guswjd', age: 25}
function no_sideEffect(object){
var copied = Object.assign({}, object)
copied.name = 'guswjd2'
return copied
}
var manipulated = no_sideEffect(object)
console.log(manipulated)
console.log(object)
manipulated == object
위 예시 코드는 Side-Effect 없이 객체를 수정하는 방법이다.
다음과 같이 Object.assign({}, object)를 이용해 얕은 복사를 통해 새로운 객체를 생성하여 수정 후 반환할 수 있다.
해당 방식으로 원본 객체의 상태를 그대로 유지하면서, 변경된 새로운 객체를 반환하고 사용할 수 있다.
React에서 불변성이 중요한 이유 React에서 불변성은 리렌더링을 효율적으로 관리하기 위해 필수적이다. React는 상태 변경을 감지할 때 객체의 주소가 바뀌었는지를 기준으로 한다. 따라서 불변성을 유지하면, React는 상태가 변경되었음을 쉽게 감지하고 필요한 부분만 리렌더링할 수 있다.
[JavaScript] 함수형 프로그래밍 패러다임 : 일급함수&순수함수
01. 일급 함수 : 함수 변수 + 함수 파라미터 + 함수 반환
#1. 일급 객체
: 다른 객체에 일반적으로 적용 가능한 연산을 모두 지원하는 객체
: 함수에 인자로 넘기기, 수정하기, 변수에 대입하기와 같은 연산을 지원
💡 일급 객체 특성
- 변수에 담을 수 있다.
- 파라미터로 전달할 수 있다.
- 함수의 반환값으로 사용할 수 있다.
#2. 일급 함수
일급 함수는 함수를 변수에 할당 + 다른 함수에 인수(파라미터)로 전달 + 함수에서 값으로 반환할 수 있다.
자바스크립트에서 함수는 일급 객체의 조건을 만족하므로 일급 객체가 된다.
즉, 일급 함수는 함수를 일급 객체로 취급하는 것으로, 함수가 일급 객체라는 것은 함수를 객체와 동일하게 사용할 수 있다는 의미이다.
02. 순수 함수
순수 함수는 참조 투명성과 부수 효과가 없는(No-Side Effect) 특징을 가진다.
이때, 참조 투명성은 함수가 외부 상태에 의존하지 않는 것이고, No-Side Effect는 함수가 외부 상태를 변경하지 않는 다는 것을 의미한다. No-Side Effect는 참조 투명성에 포함관계를 가지는 것으로 볼 수 있으며, 이 두가지 특성은 아래에서 더 자세히 다루고자 한다.
순수 함수의 특성은 멀티 스레드 환경에서 스레드 안전성(Thread-Safe)을 보장하는데 매우 중요하다.
#1. 순수 함수 장점
#2. 참조 투명성(Referential Transparency) 사례
위 예시는 참조 투명성을 위배한 사례 중 하나이다.
참조 투명성은 동일한 입력에 대해 항상 동일한 출력을 반환하는 함수의 특성을 말한다.
참조 투명성을 지키는 함수는 외부 상태에 의존하지 않으며, 함수 호출이 프로그램의 다른 부분에 영향을 미치지 않아야 한다.
위의 예시에서 함수 refer는 입력 값 a, b 외에 외부 변수 c에 의존하고 있다.
외부 변수 c는 함수 외부에서 선언되고 나중에 값이 변경된다. 이로 인해 refer 함수는 동일한 인자 1, 2를 전달받았음에도 c의 값이 변경되면서 서로 다른 결과를 반환한다. 첫 번째 refer(1, 2) 호출 시, c의 값은 3이므로 출력은 6, 두 번째 refer(1, 2) 호출 시, c의 값은 5로 변경되었으므로 출력은 8의 결과가 나온다. 이와 같은 이유로 위의 예시는 참조 투명성을 위배한 사례라 볼 수 있다.
#2. Side-Effect 사례
부수 효과(Side-Effect)는 함수가 외부 상태를 변경하거나, 외부에서 접근 가능한 상태에 영향을 미치는 경우를 말한다.
이 코드에서는 자바스크립트의 객체 object를 사용하여 함수 호출 시 부수 효과(Side Effect)가 발생하는 예시이다.
sideEffect_type1 함수는 Side-Effect를 일으킨다. 함수가 외부 변수 object를 직접 변경하기 때문에, 함수 호출 전후로 object의 상태가 달라지게 된다. 해당 코드를 실행하면 콘솔에 {name: 'guswjd2', age: 25}가 출력되는 결과를 볼 수 있다.
다음과 같이 파라미터를 통해 객체를 전달받아 그 객체의 속성을 변경하는 방식이다.
하지만 여전히 side-effect를 발생시키며, 반환값 없이 함수 내부에서 객체를 변경하는 방식은 여전히 명시적이지 않다.
즉, 함수의 호출자 입장에서는 함수가 객체를 어떻게 수정할지, 수정 여부를 명확하게 이해하기 어렵고, 코드의 예측 가능성을 떨어뜨리며, 디버깅을 어렵게 만들 수 있다.
앞선 코드들의 너무 명시적이지 않은 문제는 위와 같이 해결하였다.
하지만, 함수 내부에서 object를 copied에 할당했지만, 이는 객체를 복사한 것이 아닌 같은 객체를 가리키는 또 다른 변수를 만든 것일 뿐이어서 copied.name을 변경하면 object.name도 함게 변경되는 문제가 여전히 발생한다. 함수가 반환하는 copied와 원본 object는 동일한 객체이기 때문에 함수가 반환한 manipulated와 object는 똑같은 객체를 가리켜 manipulated == object는 true인 결과가 나오는 것이다.
이와 같은 문제들을 해결하기 위해서는 객체를 완전히 복사해야 한다. 즉, 새 객체를 만들어 반환하고, 원본 객체는 변경되지 않아야 한다.
#3. Side-Effect 사례 해결 방법 : Immutability 불변성
Side-Effect를 방지하기 위해서는 불변성을 유지하는 것이 중요하다.
불변성은 함수나 코드가 외부 상태를 변경하지 않도록 보장하는 방법을 말한다.
자바스크립트에서는 객체를 불변으로 유지하기 위해 Object.freeze()를 사용하거나 const로 선언하여 재할당을 막을 수 있다.
위 예시 코드는 Side-Effect 없이 객체를 수정하는 방법이다.
다음과 같이 Object.assign({}, object)를 이용해 얕은 복사를 통해 새로운 객체를 생성하여 수정 후 반환할 수 있다.
해당 방식으로 원본 객체의 상태를 그대로 유지하면서, 변경된 새로운 객체를 반환하고 사용할 수 있다.
#4. 얕은 복사 vs 깊은 복사
◼︎ 얕은 복사
: 1계층만 복사 = 객체나 배열의 1차원(최상위) 속성들만 복사하는 방법
: 내부 참조가 공유
◼︎ 깊은 복사
: 객체, 배열의 모든 계층의 속성들을 재귀적으로 복사하여, 복사된 객체나 배열이 원본과 완전히 독립된 구조를 가지게 하는 방법
: 원복, 복사본 간 참조가 공유되지 않음
'ASAC > Front-End' 카테고리의 다른 글