Immutability - wooyeonhui/Yeonny GitHub Wiki

Immutability(๋ณ€๊ฒฝ๋ถˆ๊ฐ€์„ฑ)๋Š” ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋œ ์ดํ›„ ๊ทธ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋Š” ๋””์ž์ธ ํŒจํ„ด์„ ์˜๋ฏธํ•œ๋‹ค.Immutability์€ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ํ•ต์‹ฌ ์›๋ฆฌ์ด๋‹ค.

๊ฐ์ฒด๋Š” ์ฐธ์กฐ(reference) ํ˜•ํƒœ๋กœ ์ „๋‹ฌํ•˜๊ณ  ์ „๋‹ฌ ๋ฐ›๋Š”๋‹ค. ๊ฐ์ฒด๊ฐ€ ์ฐธ์กฐ๋ฅผ ํ†ตํ•ด ๊ณต์œ ๋˜์–ด ์žˆ๋‹ค๋ฉด ๊ทธ ์ƒํƒœ๊ฐ€ ์–ธ์ œ๋“ ์ง€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๊ธฐ ๋–„๋ฌธ์— ๋ฌธ์ œ๊ฐ€ ๋  ๊ฐ€๋Šฅ์„œ๋„ ์ปค์ง€๊ฒŒ ๋œ๋‹ค. ์ด๋Š” ๊ฐ์ฒด์˜ ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์–ด๋–ค ์žฅ์†Œ์—์„œ ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ์ฐธ์กฐ๋ฅผ ๊ณต์œ ํ•˜๋Š” ๋ชจ๋“  ์žฅ์†Œ์—์„œ ๊ทธ ์˜ํ–ฅ์„ ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์ธ๋ฐ ์ด๊ฒƒ์ด ์˜๋„ํ•œ ๋™์ž‘์ด ์•„๋‹ˆ๋ผ๋จ„ ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋‹ค๋ฅธ ์žฅ์†Œ์— ๋ณ€๊ฒฝ ์‚ฌ์‹ค์„ ํ†ต์ง€ํ•˜๊ณ  ๋Œ€์ฒ˜ํ•˜๋Š” ์ถ”๊ฐ€ ๋Œ€์‘์ด ํ•„์š”ํ•˜๋‹ค.

์˜๋„ํ•˜์ง€ ์•Š์€ ๊ฐ์ฒด์˜ ๋ณ€๊ฒฝ์ด ๋ฐœ์ƒํ•˜๋Š” ์›์ธ์˜ ๋Œ€๋‹ค์ˆ˜๋Š” โ€œ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ฐธ์กฐํ•œ ๋‹ค๋ฅธ ๊ฐ์ฒด์—์„œ ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝโ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด ๋ฌธ์ œ์˜ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ๋น„์šฉ์ด ์กฐ๊ธˆ ๋“ค์ง€๋งŒ ๊ฐ์ฒด๋ฅผ ๋ถˆ๋ณ€๊ฐ์ฒด๋กœ ๋งŒ๋“ค์–ด ํ”„๋กœํผํ‹ฐ์˜ ๋ณ€๊ฒฝ์„ ๋ฐ˜์ง€ํ•˜๋ฉฐ ๊ฐ์ฒด์˜ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋Š” ์ฐธ์กฐ๊ฐ€ ์•„๋‹Œ ๊ฐ์ฒด์˜ ๋ฐฉ์–ด์  ๋ณต์‚ฌ(defensive copy)๋ฅผ ํ†ตํ•ด ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ ๋ฃจ ๋ณ€๊ฒฝํ•œ๋‹ค. ๋˜๋Š” ObserverํŒจํ„ดใ„น์œผ๋กœ ๊ฐ์ฒด์˜ ๋ณ€์…ฉ์— ๋Œ€์ฒ˜ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

๋ถˆ๋ณ€ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ณต์ œ๋‚˜ ๋น„๊ต๋ฅผ ์œ„ํ•œ ์กฐ์ž‘์„ ๋‹จ์ˆœํ™” ํ•  ์ˆ˜ ์žˆ๊ณ  ์„ฑ๋Šฅ ๊ฐœ์„ ์—๋„ ๋„์›€์ด ๋œ๋‹ค. ํ•˜์ง€๋งŒ ๊ฐ์ฒด๊ฐ€ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋งŽ์ด ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ ์˜คํžˆ๋ ค ๋ถ€์ ์ ˆํ•œ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.

ES6์—์„œ๋Š” ๋ถˆ๋ณ€ ๋ฐ์ดํ„ฐ ํŒจํ„ด(immutable data pattern)์„ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜์—ˆ๋‹ค.

## immutable value vs. mutable value javascript์˜ ๊ธฐ๋ณธ ์ž๋ฃŒํ˜•(primitive data type)์€ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฐ’(immutable value)์ด๋‹ค.

* Boolean
* null
* unsefined
* Number
* String
* Symbol(New in ECMAScript 6)

๊ธฐ๋ณธ ์ž๋ฃŒํ˜• ์ด์™ธ์˜ ๋ชจ๋“  ๊ฐ’์€ ๊ฐ์ฒด(Object) ํƒ€์ž…์ด๋ฉฐ ๊ฐ์ฒด ํƒ€์ž…์€ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๊ฐ’(mutable value)์ด๋‹ค.์ด๋Ÿฐ ๊ฐ’์„โ€œprimitive valuesโ€๋ผ ํ•œ๋‹ค.(๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๋œป์€ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์—์„œ์˜ ๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๋œป์ด๋‹ค. ์žฌํ• ๋‹น์€ ๊ฐ€๋Šฅํ•˜๋‹ค)

var statement = โ€˜I am an immutable valueโ€™; // string์€ immutable value

var otherStr = statement.slice(8, 17);

console.log(otherStr); // โ€˜immutableโ€™ console.log(statement); // โ€˜I am an immutable valueโ€™

2ํ–‰์—์„œ String๊ฐ์ฒด์˜ slice()๋ฉ”์†Œ๋“œ๋Š” statement ๋ณ€์ˆ˜์— ์ €์žฅ๋œ ๋ฌธ์ž์—ด์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์‚ฌ์‹ค์€ ์ƒˆ๋กœ์šด ๋ฌธ์ž์—ด์„ ์ƒ์„ฑํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์žˆ๋‹ค. ๊ทธ ์ด์œ ๋Š” ๋ฌธ์ž์—ด์€ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋Š” immutable value์ด๊ธฐ ๋–„๋ฌธ์ด๋‹ค.

var arr = []; console.log(arr.length); // 0

var v2 = arr.push(2); // arr.push()๋Š” ๋ฉ”์†Œ๋“œ ์‹คํ–‰ ํ›„ arr์˜ length๋ฅผ ๋ฐ˜ํ™˜console.log(arr.length); // 1

์ƒ๊ธฐ ์˜ˆ์ œ์—์„œ v2์˜ ๊ฐ’์€ ๋ฌด์—ˆ์ธ๊ฐ€? ๋ฌธ์ž์—ด์˜ ์˜์™€ ๊ฐ™์ด ๋ฐฐ์—ด์ด ๋™์ž‘ํ•œ๋‹ค๋ฉด v2๋Š” ์ƒˆ๋กœ์šด ๋ฐฐ์—ด(ํ•˜๋‚˜์˜ ์š”์†Œ๋ฅผ ๊ฐ€์ง€๊ณ  ๊ทธ ๊ฐ’์€ 2์ธ)์„ ๊ฐ€์ง€๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฐ์ฒด์ธ arr์€ push๋ฉ”์†Œ๋“œ์— ์˜ํ•ด update๋˜๊ณ  v2์—๋Š” ๋ฐฐ์—ด์˜ ์ƒˆ๋กœ์šด length ๊ฐ’์ด ๋ฐ˜ํ™˜๋œ๋‹ค.

์ฒ˜๋ฆฌ ํ›„ ๊ฒฐ๊ณผ์˜ ๋ณต์‚ฌ๋ณธ์„ ๋ฆฌํ„ดํ•˜๋Š” ๋ฌธ์ž์—ด์˜ ๋ฉ”์†Œ๋“œ slice()์™€๋Š” ๋‹ฌ๋ฆฌ ๋ฐฐ์—ด(๊ฐ์ฒด)์˜ ๋ฉ”์†Œ๋“œ push()๋Š” ์ง์ ‘ ๋Œ€์ƒ ๋ฐฐ์—ด์„ ๋ณ€๊ฒฝํ•œ๋‹ค. ๊ทธ ์ด์œ ๋Š” ๋ฑŒ์—ด์€ ๊ฐ์ฒด์ด๊ณ  ๊ฐ์ฒด๋Š” immutable value๊ฐ€ ์•„๋‹Œ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๊ฐ’์ด๊ธฐ ๋–„๋ฌธ์ด๋‹ค.

๋‹ค๋ฅธ ์˜ˆ๋ฅผ ์•Œ์•„๋ณด์ž.

var user = {

name: 'Lee',
address: {
  city: 'Seoul'
}

};

var myName = user.name; // ๋ณ€์ˆ˜ myName์€ string ํƒ€์ž…์ด๋‹ค.

user.name = โ€˜Kimโ€™; console.log(myName); // Lee

myName = user.name; // ์žฌํ• ๋‹นconsole.log(myName); // Kim

user.name์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ–ˆ์ง€๋งŒ ๋ณ€์ˆ˜ myName์˜ ๊ฐ’์€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š”๋‹ค. ์ด๋Š” user.name์˜ ํƒ€์ž… string์ด ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

var user1 = {

name: 'Lee',
address: {
  city: 'Seoul'
}

};

var user2 = user1; // ๋ณ€์ˆ˜ user2๋Š” ๊ฐ์ฒด ํƒ€์ž…์ด๋‹ค.

user2.name = โ€˜Kimโ€™;

console.log(user1.name); // Kim console.log(user2.name); // Kim

์œ„์˜ ๊ฒฝ์šฐ ๊ฐ์ฒด user2์˜ name ํ”„๋กœํผํ‹ฐ์— ์ƒˆ๋กœ์šด ๊ฐ’์„ ํ• ๋‹นํ•˜๋ฉด ๊ฐ์ฒด๋Š” ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฐ’์ด ์•„๋‹ˆ๋ฏ€๋กœ ๊ฐ์ฒด user2๋Š” ๋ณ€๊ฒฝ๋œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋ณ€๊ฒฝํ•˜์ง€๋„ ์•Š์€ ๊ฐ์ฒด user1๋„ ๋™์‹œ์— ๋ณ€๊ฒฝ๋œ๋‹ค. ์ด๋Š” user1๊ณผ user2๊ฐ€ ๊ฐ™์€ ์–ด๋“œ๋ ˆ์Šค๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๊ธฐ ๋–„๋ฌธ์ด๋‹ค.

== ๋ถˆ๋ณ€ ๋ฐ์ดํ„ฐ ํŒจํ„ด(immutable data pattern)ยถ โ†‘

์˜๋„ํ•˜์ง€ ์•Š์€ ๊ฐ์ฒด์˜ ๋ณ€๊ฒฝ์ด ๋ฐœ์ƒํ•˜๋Š” ์›์ธ์˜ ๋Œ€๋‹ค์ˆ˜๋Š” โ€œ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ฐธ์กฐํ•œ ๋‹ค๋ฅธ ๊ฐ์ฒด์—์„œ ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝโ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด ๋ฌธ์ œ์˜ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ๋น„์šฉ์€ ์กฐ๊ธˆ ๋“ค์ง€๋งŒ ๊ฐ์ฒด๋ฅผ ๋ถˆ๋ณ€๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ํ”„๋กœํผํ‹ฐ์˜ ๋ณ€๊ฒฝ์„ ๋ฐฉ์ง€ํ•˜๋ฉฐ ๊ฐ์ฒด์˜ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋Š” ์ฐธ์กฐ๊ฐ€ ์•„๋‹Œ ๋ฐฉ์–ด์  ๋ณต์‚ฌ(defensive copy)๋ฅผ ํ†ตํ•ด ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ ํ•œ ํ›„ ๋ณ€๊ฒฝํ•œ๋‹ค.

์ด๋ฅผ ์ •๋ฆฌํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

* ๊ฐ์ฒด์˜ ๋ฐฉ์–ด์  ๋ณต์‚ฌ(defensive copy)
Object.assign
* ๋ถˆ๋ณ€๊ฐ์ฒดํ™”๋ฅผ ํ†ตํ•œ ๊ฐ์ฒด ๋ณ€๊ฒฝ ๋ฐฉ์ง€
Object.freeze

=== Object.assignยถ โ†‘

Object.assign์€ ํƒ€ํ‚ท ๊ฐ์ฒด๋กœ ์†Œ์Šค ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ณต์‚ฌํ•œ๋‹ค. ์ด๋–„ ์†Œ์Šค ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ์™€ ๋™์ผํ•œ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง„ ํƒ€์ผ“ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋“ค์€ ์†Œ์Šค ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋กœ ๋ฎ์–ด์“ฐ๊ธฐ๋œ๋‹ค. ๋ฆฌํ„ด๊ฐ’์œผ๋กœ ํƒ€ํ‚ท ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ES6์—์„œ ์ถ”๊ฐ€๋œ ๋ฉ”์†Œ๋“œ์ด๋ฉฐ Internet Explorer๋Š” ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค.

// Syntax Object.assign(target, โ€ฆsources)

// Copy const obj = { a: 1 }; const copy = Object.assign({}, obj); console.log(copy); // { a: 1 } console.log(obj == copy); // false

// Merge const o1 = { a: 1 }; const o2 = { b: 2 }; const o3 = { c: 3 };

const merge1 = Object.assign(o1, o2, o3);

console.log(merge1); // { a: 1, b: 2, c: 3 } console.log(o1); // { a: 1, b: 2, c: 3 }, ํƒ€๊ฒŸ ๊ฐ์ฒด๊ฐ€ ๋ณ€๊ฒฝ๋œ๋‹ค!

// Merge const o4 = { a: 1 }; const o5 = { b: 2 }; const o6 = { c: 3 };

const merge2 = Object.assign({}, o4, o5, o6);

console.log(merge2); // { a: 1, b: 2, c: 3 } console.log(o4); // { a: 1 }

Object.assign์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ๊ฐ์ฒด๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

const user1 = {

name: 'Lee',
address: {
  city: 'Seoul'
}

};

const user2 = Object.assign({}, user1); // user1์„ {}์— Copy

user2.name = โ€˜Kimโ€™;

// ์ƒ๊ธฐ 2ํ–‰์€ ์•„๋ž˜์™€ ๋™์น˜์ด๋‹ค. // {name: โ€˜Kimโ€™}์€ user1์— ๋ณ‘ํ•ฉ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ฒซ๋ฒˆ์งธ ์ธ์ž์ธ {}์— ๋ณ‘ํ•ฉ๋œ๋‹ค. // const user2 = Object.assign({}, user1, {name: โ€˜Kimโ€™});

console.log(user1.name); // Lee console.log(user2.name); // Kim

user1 ๊ฐ์ฒด๋ฅผ ๋นˆ๊ฐ์ฒด์— ๋ณต์‚ฌํ•˜์—ฌ ์ƒˆ๋กœ์šด ๊ฐ์ฒด user2๋ฅผ ์ƒ์„ฑํ•˜์˜€๋‹ค. user1๊ณผ user2๋Š” ์–ด๋“œ๋ ˆ์Šค๋ฅผ ๊ณต์œ ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ํ•œ ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜์—ฌ๋„ ๋‹ค๋ฅธ ๊ฐ์ฒด์— ์•„๋ฌด๋Ÿฐ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค.

์ฃผ์˜ํ•  ๊ฒƒ์€ user1 ๊ฐ์ฒด๋Š” const๋กœ ์„ ์–ธ๋˜์–ด ์žฌํ• ๋‹น์€ ํ•  ์ˆ˜ ์—†์ง€๋งŒ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๋Š” ๋ณดํ˜ธ๋˜์ง€ ์•Š๋Š”๋‹ค. ๋‹ค์‹œ ๋งํ•˜์ž๋ฉด ๊ฐ์ฒด์˜ ๋‚ด์šฉ์€ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

Object.freezeยถ โ†‘

Object.freeze()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ถˆ๋ณ€(immutable) ๊ฐ์ฒด๋กœ ๋งŒ๋“ค์ˆ˜ ์žˆ๋‹ค.

const user1 = {

name: 'Lee',
address: {
  city: 'Seoul'
}

};

const user2 = Object.assign({}, user1, {name: โ€˜Kimโ€™});

console.log(user1.name); // Lee console.log(user2.name); // Kim

Object.freeze(user1);

user1.name = โ€˜Kimโ€™; // ๋ฌด์‹œ๋œ๋‹ค!

console.log(user1); // { name: โ€˜Leeโ€™, address: { city: โ€˜Seoulโ€™ } }

console.log(Object.isFrozen(user1)); // true

ํ•˜์ง€๋งŒ ๊ฐ์ฒด ๋‚ด๋ถ€์˜ ๊ฐ์ฒด(Nested Object)๋Š” ๋ณ€๊ฒฝ๊ฐ€๋Šฅํ•˜๋‹ค.

const user = {

name: 'Lee',
address: {
  city: 'Seoul'
}

};

Object.freeze(user);

user.address.city = โ€˜Busanโ€™; // ๋ณ€๊ฒฝ๋œ๋‹ค! console.log(user); // { name: โ€˜Leeโ€™, address: { city: โ€˜Busanโ€™ } }

๋‚ด๋ถ€ ๊ฐ์ฒด๊นŒ์ง€ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค๋ ค๋ฉด Deep freeze๋ฅผ ํ•˜์—ฌ์•ผ ํ•œ๋‹ค.

function deepFreeze(obj) {

const props = Object.getOwnPropertyNames(obj);

props.forEach((name) => {
  const prop = obj[name];
  if(typeof prop === 'object' && prop !== null) {
    deepFreeze(prop);
  }
});
return Object.freeze(obj);

}

const user = {

name: 'Lee',
address: {
  city: 'Seoul'
}

};

deepFreeze(user);

user.name = โ€˜Kimโ€™; // ๋ฌด์‹œ๋œ๋‹คuser.address.city = โ€˜Busanโ€™; // ๋ฌด์‹œ๋œ๋‹ค

console.log(user); // { name: โ€˜Leeโ€™, address: { city: โ€˜Seoulโ€™ } }

Immutable.jsยถ โ†‘

Object.assign๊ณผ Object.freeze์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ถˆ๋ณ€ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์€ ๋ฒˆ๊ฑฐ๋Ÿฌ์šธ ๋ฟ๋”๋Ÿฌ ์„ฑ๋Šฅ์ƒ ์ด์Šˆ๊ฐ€ ์žˆ์–ด์„œ ํฐ ๊ฐ์ฒด์—๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ๋˜ ๋‹ค๋ฅธ ๋Œ€์•ˆ์œผ๋กœ Facebook์ด ์ œ๊ณตํ•˜๋Š” Immutable.js๋ฅผ ์‚ฌ์šฉํ—ˆ๋ˆˆ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค. Immutable.js๋Š” List,Stack,Map,OrderedMap,Set,OrderedSet,Record์™€ ๊ฐ™์€ ์˜๊ตฌ ๋ถˆ๋ณ€(Permit Immutable)๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. npm์„ ์‚ฌ์šฉํ•˜์—ฌ Immutable.js๋ฅผ ์„ค์น˜ํ•œ๋‹ค.

$ npm install immutable

Immutable.js์˜ Map ๋ชจ๋“ˆ์„ ์ž„ํฌํŠธํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.

const { Map } = require(โ€˜immutableโ€™) const map1 = Map({ a: 1, b: 2, c: 3 }) const map2 = map1.set(โ€˜bโ€™, 50) map1.get(โ€˜bโ€™) // 2 map2.get(โ€˜bโ€™) // 50

โš ๏ธ **GitHub.com Fallback** โš ๏ธ