๐Ÿ“– TIL - ๋ฐฐ์—ด๊ณผ ๊ฐ์ฒด์˜ ๋น„๋ฐ€์Šค๋Ÿฌ์šด ๋™๊ฑฐ: ๋ฉ”๋ชจ๋ฆฌ ์† ๊ทธ๋“ค์˜ ์ด์•ผ๊ธฐ

์Š˜ยท2025๋…„ 1์›” 8์ผ

๐Ÿ“– TIL

๋ชฉ๋ก ๋ณด๊ธฐ
19/90

โœจ ์ƒˆ๋กญ๊ฒŒ ๋ฐฐ์šด ์ 

๐Ÿ”„ ์ฐธ์กฐํ˜• ๋ฐ์ดํ„ฐ์˜ ํŠน์ง•

  • ๋ฉ”๋ชจ๋ฆฌ์— ๊ฐ’์ด ์ €์žฅ๋œ ์ฃผ์†Œ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ํƒ€์ž… (๊ฐ์ฒด, ๋ฐฐ์—ด, ํ•จ์ˆ˜)
  • ๊ฐ’์„ ์ง์ ‘ ๊ฐ€์ง€์ง€ ์•Š๊ณ  ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ด
  • ๋™์ผํ•œ ์ฐธ์กฐํ˜• ๋ณ€์ˆ˜๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ๋งŒ๋“ค๋ฉด ๊ฐ™์€ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๋ฅผ ๊ณต์œ 

๐Ÿ’พ ๋ฉ”๋ชจ๋ฆฌ ์ €์žฅ ๊ตฌ์กฐ

  • ์ฝœ์Šคํƒ(Call Stack): ์›์‹œ๊ฐ’ ์ €์žฅ, ๊ณ ์ •๋œ ํฌ๊ธฐ
  • ํž™(Heap): ๊ฐ์ฒด/๋ฐฐ์—ด/ํ•จ์ˆ˜ ์ €์žฅ, ๋™์  ํฌ๊ธฐ

๐Ÿ“ฆ ๋ฐฐ์—ด๊ณผ ๊ฐ์ฒด ๋‹ค๋ฃจ๊ธฐ

  • ๋ฐฐ์—ด: ์ˆœ์„œ๊ฐ€ ์žˆ๋Š” ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ
  • ๊ฐ์ฒด: computed property๋ฅผ ํ†ตํ•ด ๋™์ ์œผ๋กœ key ๊ฐ’ ์ •์˜ ๊ฐ€๋Šฅ
  • ๊ฐ์ฒด์˜ key๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฌธ์ž์—ด๋กœ ์ฒ˜๋ฆฌ

๐Ÿ”จ ๋ฐฐ์—ด/๊ฐ์ฒด ๋ฉ”์„œ๋“œ

๋ฐฐ์—ด ๋ฉ”์„œ๋“œ

  • ๋ณ€๊ฒฝ ๋ฉ”์„œ๋“œ(Mutable): ์›๋ณธ ๋ฐฐ์—ด ์ง์ ‘ ์ˆ˜์ •
  • ๋น„๋ณ€๊ฒฝ ๋ฉ”์„œ๋“œ(Immutable): ์ƒˆ๋กœ์šด ๋ฐฐ์—ด ๋ฐ˜ํ™˜

๊ฐ์ฒด ๋ฉ”์„œ๋“œ

  • Object.keys(): key ๋ฐฐ์—ด ๋ฐ˜ํ™˜
  • Object.values(): value ๋ฐฐ์—ด ๋ฐ˜ํ™˜
  • Object.entries(): [key, value] ์Œ ๋ฐฐ์—ด ๋ฐ˜ํ™˜
  • Object.assign(): ๊ฐ์ฒด ๋ณต์‚ฌ/๋ณ‘ํ•ฉ
  • Object.freeze(): ๊ฐ์ฒด ์ˆ˜์ • ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋™๊ฒฐ

๐Ÿ“ ๋ณต์‚ฌ์˜ ์ข…๋ฅ˜์™€ ์‚ฌ์šฉ๋ฒ•

์–•์€ ๋ณต์‚ฌ (Shallow Copy)

// 1. Object.assign()
const originalObj = { name: 'John', age: 30 };
const shallowCopy1 = Object.assign({}, originalObj);

// 2. ์Šคํ”„๋ ˆ๋“œ ์—ฐ์‚ฐ์ž
const shallowCopy2 = { ...originalObj };

// 3. ๋ฐฐ์—ด์˜ ๊ฒฝ์šฐ
const originalArray = [1, 2, { x: 1 }];
const shallowCopy3 = [...originalArray];

๊นŠ์€ ๋ณต์‚ฌ (Deep Copy)

// 1. structuredClone() - 2022๋…„ ๋„์ž…
const originalObj = { 
  name: 'John',
  address: { city: 'Seoul', country: 'Korea' },
  birth: new Date('1990-01-01'),
  skills: new Set(['JavaScript', 'React'])
};
const deepCopy1 = structuredClone(originalObj);

// 2. JSON.parse + JSON.stringify
const deepCopy2 = JSON.parse(JSON.stringify(originalObj));

// 3. ์žฌ๊ท€ ํ•จ์ˆ˜ ์‚ฌ์šฉ
function deepCopy(obj) {
  if (obj === null || typeof obj !== 'object') return obj;
  const copy = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
    copy[key] = deepCopy(obj[key]);
  }
  return copy;
}

๐Ÿ“ข ๊ฐ ๊นŠ์€ ๋ณต์‚ฌ ๋ฐฉ์‹์˜ ํŠน์ง•๊ณผ ์ฃผ์˜์‚ฌํ•ญ

structuredClone()

  • โœ… ์žฅ์ 
    • Date, Set, Map ๋“ฑ ๋‹ค์–‘ํ•œ ๋‚ด์žฅ ํƒ€์ž… ์ง€์›
    • ์ˆœํ™˜ ์ฐธ์กฐ(Circular Reference) ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
    • ์‚ฌ์šฉํ•˜๊ธฐ ๊ฐ„ํŽธํ•จ
  • โš ๏ธ ์ฃผ์˜์‚ฌํ•ญ
    • 2022๋…„์— ๋„์ž…๋œ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์œผ๋กœ ๊ตฌ๋ฒ„์ „ ๋ธŒ๋ผ์šฐ์ € ์ง€์› ์ œํ•œ
    • ํ•จ์ˆ˜(Function) ๋ณต์‚ฌ ๋ถˆ๊ฐ€๋Šฅ

JSON.parse(JSON.stringify())

  • โœ… ์žฅ์ 
    • ๊ตฌํ˜„์ด ๊ฐ„๋‹จํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์›€
    • ๋ธŒ๋ผ์šฐ์ € ํ˜ธํ™˜์„ฑ์ด ์ข‹์Œ
  • โš ๏ธ ์ฃผ์˜์‚ฌํ•ญ
    • undefined, ํ•จ์ˆ˜, Symbol ๊ฐ’ ์†์‹ค
    • Date ๊ฐ์ฒด๊ฐ€ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜๋จ
    • Set, Map ๋“ฑ์˜ ํŠน์ˆ˜ ๊ฐ์ฒด ์ฒ˜๋ฆฌ ๋ถˆ๊ฐ€
    • ์ˆœํ™˜ ์ฐธ์กฐ ์‹œ ์˜ค๋ฅ˜ ๋ฐœ์ƒ
// JSON ๋ฐฉ์‹์˜ ํ•œ๊ณ„ ์˜ˆ์‹œ
const obj = {
  func: () => console.log('Hello'),
  symbol: Symbol('sym'),
  undefined: undefined,
  date: new Date(),
  set: new Set([1, 2, 3])
};

const copied = JSON.parse(JSON.stringify(obj));
console.log(copied);
// ์ถœ๋ ฅ:
// {
//   date: "2024-01-08T00:00:00.000Z", // Date๊ฐ€ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜
//   set: {},                          // Set์ด ๋นˆ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜
//   // func, symbol, undefined๋Š” ์™„์ „ํžˆ ์‚ฌ๋ผ์ง
// }

๐ŸŽฏ ๋ณต์‚ฌ ๋ฐฉ์‹ ์„ ํƒ ์‹œ์ 

์–•์€ ๋ณต์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ

  1. ๋‹จ์ˆœํ•œ ๊ฐ์ฒด/๋ฐฐ์—ด ๋ณต์‚ฌ
// ์‚ฌ์šฉ์ž ์ •๋ณด ์ˆ˜์ • ์‹œ
const userInfo = { name: 'John', age: 30 };
const updatedInfo = { ...userInfo, age: 31 };
  1. ์ƒํƒœ ์—…๋ฐ์ดํŠธ ์‹œ (React ๋“ฑ)
// ๋ฆฌ์•กํŠธ ์ƒํƒœ ์—…๋ฐ์ดํŠธ
const [todos, setTodos] = useState([]);
const addTodo = (newTodo) => {
  setTodos([...todos, newTodo]); // ์–•์€ ๋ณต์‚ฌ๋กœ ์ถฉ๋ถ„
};

๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ

  1. ์ค‘์ฒฉ๋œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ ๋‹ค๋ฃฐ ๋•Œ
const companyData = {
  name: 'Tech Corp',
  departments: [{
    name: 'Engineering',
    employees: [{ name: 'John', projects: ['A', 'B'] }]
  }]
};

// ์™„์ „ํ•œ ๋…๋ฆฝ ๋ณต์‚ฌ๋ณธ ํ•„์š”์‹œ
const backupData = deepCopy(companyData);
  1. ์›๋ณธ ๋ฐ์ดํ„ฐ ๋ณด์กด์ด ์ค‘์š”ํ•  ๋•Œ
// ๊ฒŒ์ž„ ์ƒํƒœ ์ €์žฅ ์‹œ์Šคํ…œ
const gameState = {
  player: { position: {x: 0, y: 0}, inventory: ['sword'] },
  world: { entities: [], weather: 'sunny' }
};

// ์„ธ์ด๋ธŒ ํฌ์ธํŠธ ์ƒ์„ฑ
const savePoint = deepCopy(gameState);

๐Ÿš€ ์ด๋Ÿฐ ์ ์ด ํšจ์œจ์ ์ด์—์š”

  • ์–•์€ ๋ณต์‚ฌ: ์„ฑ๋Šฅ์ด ์ค‘์š”ํ•˜๊ฑฐ๋‚˜ ๋‚ด๋ถ€ ์†์„ฑ์ด ์›์‹œ๊ฐ’๋งŒ ์žˆ๋Š” ๊ฒฝ์šฐ
  • ๊นŠ์€ ๋ณต์‚ฌ: ์ค‘์ฒฉ ๊ฐ์ฒด์ด๊ฑฐ๋‚˜ ๋‚ด๋ถ€ ์†์„ฑ ๋ณ€๊ฒฝ ์‹œ ์›๋ณธ ๋ณดํ˜ธ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ
  • ์ตœ์‹  ํ™˜๊ฒฝ์—์„œ๋Š” structuredClone()์„ ์‚ฌ์šฉํ•˜๊ณ , ๊ตฌ๋ฒ„์ „ ๋ธŒ๋ผ์šฐ์ € ์ง€์›์ด ํ•„์š”ํ•˜๊ฑฐ๋‚˜ ๊ฐ„๋‹จํ•œ ๊ฐ์ฒด ๋ณต์‚ฌ์˜ ๊ฒฝ์šฐ JSON ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํšจ์œจ์ 

โญ๏ธ ์ฐธ๊ณ  ์ž๋ฃŒ

  • Does it mutate? : ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ์˜ ๋ณ€๊ฒฝ/๋น„๋ณ€๊ฒฝ ์—ฌ๋ถ€ ํ™•์ธ ์‚ฌ์ดํŠธ
profile
์ฃผ๋‹ˆ์–ด ํ”„๋ก ํŠธ์—”๋“œ ์„ฑ์žฅ๊ธฐ ๊ธฐ๋ก๊ธฐ๋ก

0๊ฐœ์˜ ๋Œ“๊ธ€