๐Ÿ“ŒLanguage/JavaScript

[TIL]๊ฐ์ฒด ๋ถˆ๋ณ€์„ฑ, ๊ฐ์ฒด๋ฅผ immutableํ•˜๊ฒŒ ๋‹ค๋ฃจ๋Š” ๋ฐฉ๋ฒ•, ๋ฐฐ์—ด์„ immutableํ•˜๊ฒŒ ๋‹ค๋ฃจ๋Š” ๋ฐฉ๋ฒ•

hellohailie 2023. 1. 5. 12:44

๊ฐ์ฒด ๋ถˆ๋ณ€์„ฑ์ด๋ž€?

immutability = ๋ณ€ํ™”๊ฐ€๋Šฅํ•˜์ง€ ์•Š์Œ

๐Ÿ‘‰ ๋ฐ์ดํ„ฐ์˜ ์›๋ณธ์ด ํ›ผ์†๋˜๋Š” ๊ฒƒ์„ ๋ง‰๋Š”๋‹ค. 

 

 

<์›์‹œ๋ฐ์ดํ„ฐํƒ€์ž…> => ๋ถˆ๋ณ€ (immutability), ํ•„์š”ํ• ๋•Œ๋งŒ ์ƒˆ๋กœ ๋งŒ๋“ ๋‹ค. 

  • String
  • Number
  • Boolean
  • Null
  • Undefined
  • Symbol

<๊ฐ์ฒด> => ๊ฐ€๋ณ€ (mutability), ์ƒ์„ฑํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ ๋งŒ๋“ ๋‹ค. 

  • Object
  • Array
  • Function
let p1 = 1;
let p2 = 1;
console.log(p1, p2, p1 === p2);

// 1,1,true
// ์›์‹œ๋ฐ์ดํ„ฐ ํƒ€์ž…์€ ๊ฐ’์ด ๊ฐ™์œผ๋ฉด ๊ฐ™์€ ๊ณณ์„ ๊ฐ€๋ฆฌ์ผœ์„œ true๋‹ค.

let o1 = {name:'hailie'}
let o2 = {name:'hailie'}
console.log(o1, o2, o1 === o2);

// {name:'hailie'}, {name:'hailie'}, false
// ๊ฐ’์€ ๊ฐ™์ง€๋งŒ ์„œ๋กœ ๋ณ„๋„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์— false์ด๋‹ค.

let o3 = o1;
o3.name = 'coco'

console.log('o3:',o3, 'o1:',o1)
// o3: {name: 'coco'} o1: {name: 'coco'}
// o3์˜ value๋ฅผ ๋ฐ”๊ฟจ์ง€๋งŒ ๋ณธ์˜์•„๋‹ˆ๊ฒŒ o1์˜ value๊นŒ์ง€ ๋ฐ”๊ฟ”๋ฒ„๋ ธ๋‹ค!

 

let o1 = {name:'hailie'}
let o2 = {name:'hailie'}

let o3 = o1;
o3.name = 'coco'

console.log('o3:',o3, 'o1:',o1)

// o3: {name: 'coco'} o1: {name: 'coco'}
// o3์˜ value๋ฅผ ๋ฐ”๊ฟจ์ง€๋งŒ ๋ณธ์˜์•„๋‹ˆ๊ฒŒ o1์˜ value๊นŒ์ง€ ๋ฐ”๊ฟ”๋ฒ„๋ ธ๋‹ค!

 


โญ๏ธ๊ฐ์ฒด๋ฅผ immutableํ•˜๊ฒŒ ๋‹ค๋ฃจ๋Š” ๋ฐฉ๋ฒ•โญ๏ธ

๋ณต์‚ฌํ•œ ๊ฒƒ์„ ์ˆ˜์ •ํ•˜์ž!

 

let o1 = {name:'hailie'}
let o2 = Object.assign({},o1)

o2.name = 'coco'
console.log(o1 === o2) //false ๋‹ค๋ฅธ ๊ณณ์„ ๋ณด๊ณ  ์žˆ์Œ

Object.assign({},o1)์€ ๋นˆ ๊ฐ์ฒด์™€ ๋’ค์— ๋”ฐ๋ผ์˜ค๋Š” ๊ฐ์ฒด๋“ค์„ ๋ณ‘ํ•ฉํ•ด์„œ ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋กœ ๋งŒ๋“ค์–ด์„œ ๋ฆฌํ„ดํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. 

 

 


Nested object ์ค‘์ฒฉ๋œ ๊ฐ์ฒด๋กœ ๋” ๊ณต๋ถ€ํ•ด๋ณด๊ธฐ

let o1 = {name:'hailie', score:[1,2]}
let o2 = Object.assign({},o1)

o2.score.push(3)

console.log('o1:', o1, 'o2:', o2)

// o1: {name: 'hailie', score: Array(3)} 
name: "hailie" score: (3) [1, 2, 3]

o2: {name: 'hailie', score: Array(3)}
name : "hailie" score: (3) [1, 2, 3]


console.log(o1 === o2, o1.score === o2.score)
// false ture

 

Object.assign()์œผ๋กœ ๊ฐ์ฒด๋ฅผ ๋ณต์‚ฌํ•˜๋ฉด ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋“ค๋งŒ ๋ณต์ œ๊ฐ€ ๋˜๋Š”๊ฑฐ๊ณ , ๊ทธ๋Ÿฐ๋ฐ ๊ทธ ํ”„๋กœํผํ‹ฐ ์ค‘์— value๊ฐ€ object ํ˜•์ธ ๊ฒฝ์šฐ์—๋Š” ๊ฐ’์„ ๋ณต์‚ฌํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ์œ„์น˜๋ฅผ ๋ณต์ œํ•œ๋‹ค.

 

 

๊ทธ๋ž˜์„œ push๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋ง๊ณ  concat์„ ์‚ฌ์šฉํ•ด์„œ ๊ฐ’์„ ๋ณต์ œํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค. 

(push์€ ์›๋ณธ ๋ฐฐ์—ด์„ ๊ฑด๋“œ๋ฆฌ๊ณ , concat์€ ์›๋ณธ ๋ฐฐ์—ด์„ ๋ณต์ œํ•ด์„œ ์ธ์ž๋กœ ๋“ค์–ด์˜ค๋Š” ๊ฐ’์„ ์ถ”๊ฐ€ํ•œ๋‹ค. )

 

let o1 = {name:'hailie', score:[1,2]}
let o2 = Object.assign({},o1)

o2.score = o2.score.concat(3)

or

o2.score = o2.score.concat()
o2.score.push(3)


console.log('o1:', o1, 'o2:', o2)

// o1: {name: 'hailie', score: Array(2)} 
name: "hailie" score: (3) [1, 2]

o2: {name: 'hailie', score: Array(3)}
name : "hailie" score: (3) [1, 2, 3]

 

 

Object.assign()๋Š” ๋ฐฐ์—ด์ด ๊ฐ€์ง„ ํŠน์ˆ˜ํ•œ ๊ธฐ๋Šฅ์ด ์‚ฌ๋ผ์ง„๋‹ค.
๊ทธ๋ž˜์„œ ๋ฐฐ์—ด์˜ ๊ฒฝ์šฐ์—๋Š” concat, slice, Array.from()์„ ์‚ฌ์šฉํ•ด์•ผ immutableํ•˜๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค. 

 


์›๋ณธ ๊ฐ์ฒด๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ๋ชปํ•˜๋„๋ก ์›์ฒ™์ ์œผ๋กœ ๋ง‰๋Š” ๋ฐฉ๋ฒ• ๐Ÿ‘‰ Object.freeze

let o1 = {name:'hailie'}
Object.freeze(o1);
o1.name = 'coco'

console.log(o1);
// {name:'hailie'}

 

 

Object.freeze๋Š” ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ์–ผ๋ฆฐ๋‹ค. 

๊ทธ๋Ÿฐ๋ฐ ๊ทธ ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์ด ๊ฐ์ฒด๋ผ๋ฉด ์–ผ๋ฆฌ์ง€ ๋ชปํ•œ๋‹ค. 

let o1 = {name:'hailie', score:[1,2]}
Object.freeze(o1);
o1.name = 'coco'
o1.city = 'seoul'
o1.score.push(3)

console.log(o1);
// {name:'hailie', score:[1,2,3]}

 

 

๊ทธ๋ž˜์„œ ์ง์ ‘ ๊ฑฐ๊ธฐ๊นŒ์ง€ ๊ฐ€์„œ ์–ผ๋ ค์•ผํ•œ๋‹ค.

let o1 = {name:'hailie', score:[1,2]}
Object.freeze(o1);
Object.freeze(o1.score);
o1.score.push(3)

console.log(o1);
// typeerror

 


const vs. Object.freeze

const o1 = {name:'hailie'}
Object.freeze(o1)
const o2 = {name:'hailie'}

o1 = o2 ๐Ÿ‘‰ const๊ฐ€ ๋ฐœ๋™ํ•ด์„œ ์—๋Ÿฌ๊ฐ€ ๋‚˜์˜จ๋‹ค. o1๊ฐ€ ๊ฐ€๋ฆฌํ‚ฌ ๋Œ€์ƒ์„ ๋ชป๋ฐ”๊พธ๊ฒŒ ํ•œ๋‹ค. 
o1.name = 'lee' ๐Ÿ‘‰ Object.freeze()๊ฐ€ ๋ฐœ๋™ํ•ด์„œ ๊ฐ’ ์•ˆ๋ฐ”๋€๋‹ค. ๊ฐ’ ์ž์ฒด๋ฅผ ๋ชป๋ฐ”๊พธ๊ฒŒ ํ•œ๋‹ค.

 

๐Ÿ‘‰ const = ๊ฐ€๋ฆฌํ‚ฌ ๋Œ€์ƒ์„ ๋ชป๋ฐ”๊พธ๊ฒŒ ํ•œ๋‹ค. 
๐Ÿ‘‰ Object.freeze() =  ๊ฐ’ ์ž์ฒด๋ฅผ ๋ชป๋ฐ”๊พธ๊ฒŒ ํ•œ๋‹ค. 

 

 


๋ถˆ๋ณ€์„ฑ์€ ์›๋ณธ์„ ํ›ผ์†ํ•˜์ง€ ์•Š๊ณ  ๋ณต์ œ๋ฅผ ํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ์›๋ณธ๊ณผ ๋ณต์ œ๋ณธ์€ ์„œ๋กœ ๋…๋ฆฝ๋œ ์ƒํƒœ์ด๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋กœ์—๊ฒŒ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์•„์„œ, ๊ฒฐ๊ณผ์ ์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์˜ˆ๊ธฐ์น˜ ์•Š๊ฒŒ ๋™์ž‘ํ•˜๋Š” side effect๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค. 

๊ทธ๋ ‡๋‹ค๊ณ  ๋ถˆ๋ณ€ํ•จ์ด ๊ฐ€๋ณ€ํ•จ๋ณด๋‹ค ์šฐ์›”ํ•œ ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค!

 

๋‹ค๋งŒ, ์ปดํ“จํ„ฐ ๋ถ„์•ผ๊ฐ€ ์›Œ๋‚™ ์œ ์—ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— (๊ฐ€๋ณ€์ด๊ธฐ ๋•Œ๋ฌธ์—) ์ƒ๊ธฐ๋Š” ๋ฌธ์ œ๋ฅผ ์™„ํ™”ํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ถˆ๋ณ€์ด ๊ฐ•์กฐ๋  ๋ฟ์ด๋‹ค!

 

 


์ถ”๊ฐ€๋กœ ๊ณต๋ถ€ํ•ด๋ณด๊ณ  ์‹ถ์€ ๊ฒƒ

๊ฐ์ฒด์ง€ํ–ฅ => ๊ฐ์ฒด๋ฅผ ๋ถ€ํ’ˆ์œผ๋กœ ์‚ฌ์šฉํ•ด์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค์–ด๊ฐ€๋Š” ํŒจ๋Ÿฌ๋‹ค์ž„

ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ => ํ•จ์ˆ˜๋ฅผ ๋ถ€ํ’ˆ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ํŒจ๋Ÿฌ๋‹ค์ž„ (๋ถˆ๋ณ€์„ฑ์„ ์ž˜ ํ™œ์šฉํ•œ ์ˆœ์ˆ˜ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž)

 

 

๋ถˆ๋ณ€์„ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ => ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ์ค„์—ฌ์ค„ ์ˆ˜ ์žˆ๋‹ค. 

immutable

immer

mori