코딩 공부/React

[React] 3.3.1 불변성(함수형 프로그래밍의 개념) - 가온 코딩

Cosmic-dust 2022. 7. 25. 15:36
728x90
반응형

함수형 프로그래밍의 핵심 개념인

1. 불변성(immutability)

2. 순수성(purity)

3. 데이터 변환(transformation)

4. 고차 함수

5. 재귀(recursion)

중 불변성에 대해 설명하겠다.

 

Immutability(불변성)

mutate 라는 영어 단어는 변한다는 뜻이다.

따라서 immutable는 변할 수 없다는 뜻이다.

함수형 프로그래밍에서는 데이터가 변할 수 없고 불변성 데이터는 결코 바뀌지 않는다.

 

1. Mutations

색에 평점을 메기는 함수를 만든다고 했을 때, 함수는 넘겨받은 color 객체의 rating 을 변경한다.

let color_lawn = {
    title: "lawn",
    color: "#00FF00",
    rating: 0
}

function rateColor(color, rating) {
  color.rating = rating
  return color
} 

//
// rateColor Mutates the origional color
//

console.log(rateColor(color_lawn, 5).rating)	// 5
console.log(color_lawn.rating)	// 5

자바스크립트에서 함수의 인자는 실제 데이터에 대한 참조다. rateColor 함수 안에서 color의 rating을 변경하면 원본 color_lawn객체의 rating도 바뀐다.

 

이때, rateColor를 아래와 같이 고쳐쓰면 원본은 그대로 두고 rating 값을 변경할 수 있다.

 

2. Object.assign()

여기서는 Object.assign을 사용해 rating을 바꿨는데 Object.assign은 복사기와 같다. 빈 객체를 받고, color 객체를 그 빈 객체에 복사한 다음, 복사본에 있는 rating 프로퍼티의 값을 rating 파라미터의 값으로 변경한다. 이제 원본은 그대로 둔 채 rating만 변경된 복사본이 생기게 된다.

let color_lawn = {
    title: "lawn",
    color: "#00FF00",
    rating: 0
}

var rateColor = function(color, rating) {
   return Object.assign({}, color, {rating:rating})
} 

//
// Using Object.assign to create a copy and rate that
//

console.log(rateColor(color_lawn, 5).rating)  // 5
console.log(color_lawn.rating)	// 0

 

3. Spread Operator with Objects(객체 스프레드 연산자)

화살표 함수와 객체 스프레드 연산자를 활용해 같은 함수를 작성할 수도 있다.

rateColor 함수는 스프레드 연산자를 사용해 원본 color를 새로운 객체 안에 복사한 다음에 그 rating 프로퍼티를 덮어쓴다.

let color_lawn = {
    title: "lawn",
    color: "#00FF00",
    rating: 0
}

const rateColor = (color, rating) => 
    ({
        ...color,
        rating
    })

//
// Or the ...spread operator, even better
//

console.log(rateColor(color_lawn, 5).rating)
console.log(color_lawn.rating)

이러한 rateColor 함수는 앞에 예제의 rateColor 함수와 똑같은 일을 한다. 이 함수는 color를 변경불가능한 객체로 취급하고 더 짧다.

여기서 반환할 객체를 괄호(())로 감쌌다. 왜냐하면 화살표 함수의 본문에서 바로 중괄호({})를 사용해 객체를 반환할 수 없기 때문이다. 

 

4. Array.push()

색의 이름으로 이루어진 배열에 Array.push를 사용해 색을 추가하는 함수를 작성할 수 있다.

let list = [
    { title: "Rad Red"},
    { title: "Lawn"},
    { title: "Party Pink"}
]

var addColor = function(title, colors) {
  colors.push({ title: title })
  return colors
}

//
// Add Color is mutating the origional list
//

console.log(addColor("Glam Green", list).length) // 4
console.log(list.length)	// 4

하지만 Array.push는 불변성 함수가 아니다.

addColor 함수는 원본 배열에 새로운 원소를 추가한다.

원본 list 배열에 손을 대지 않고 추가하기 위해서는 Array.concat을 사용해야 한다.

 

5. Array.concat()

 

let list = [
    { title: "Rad Red"},
    { title: "Lawn"},
    { title: "Party Pink"}
]

const addColor = (title, array) => array.concat({title})

//
// Use array.concat instead, it does not mutate the list
//

console.log(addColor("Glam Green", list).length) 
console.log(list.length)

Array.concat은 두 배열을 붙여주고 새로운 객체를 받는다. 그 객체에는 새로운 색의 이름이 title이라는 이름의 프로퍼티로 들어 있다. Array.concat은 그 객체를 원래의 배열을 복사한 새로운 배열 뒤에 추가한다.

 

 

 

6. Spread Operator with Arrays(배열 스프레드 연산자)

앞에서 객체를 복사할 때 사용한 방법과 같이, 배열 스프레드 연산자를 사용해서 배열을 복사할 수 있다.아래는 앞의 addColor 함수를 새로운 자바스크립트 버전으로 작성한 코드이다.

let list = [
    { title: "Rad Red"},
    { title: "Lawn"},
    { title: "Party Pink"}
]

const addColor = (title, list) => [...list, {title}]

//
// Even Better, ...spread operator
//

console.log(addColor("Glam Green", list).length) 
console.log(list.length)

이 함수는 원본 list의 원소들을 새로운 배열에 복사하고, title 파라미터로 받은 값을 title 프로퍼티로 하는 객체를 새 배열 뒤에 추가한다. 이 함수는 인자로 받은 list 를 변경하지 않기 때문에 list의 원본인 colorArray의 불변성을 지켜준다.

 

 

참고자료

러닝 리액트(Learning React), 알렉스 뱅크스, 한빛미디어 (2021)

728x90
반응형