-
์์ ๋ณต์ฌ์ ๊น์ ๋ณต์ฌ์นดํ ๊ณ ๋ฆฌ ์์ 2023. 2. 10. 02:14
TLDR;
์์ ๋ณต์ฌ๋ ์ฐธ์กฐ๊ฐ์ ๋ณต์ฌํ๋ ๊ฒ์ด๋ฉฐ, ๊น์ ๋ณต์ฌ๋ ๋ด๋ถ์ ๊ฐ์ ๋ณต์ฌํ์ฌ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ง๋๋ ๊ฒ์ ์๋ฏธํ๋ค. ์์ ๋ณต์ฌ๋ ์ฐธ์กฐ๊ฐ ๋ณต์ฌ์ด๊ธฐ์ ๋ณต์ฌ๋ณธ ๋ณ๊ฒฝ ์ ์๋ณธ์ด ๋ณ๊ฒฝ๋์ง๋ง, ๊น์ ๋ณต์ฌ๋ ์์ ์๋ก์ด ๊ฐ์ฒด์ด๊ธฐ ๋๋ฌธ์ ๋ณต์ฌ๋ณธ ๋ณ๊ฒฝ์๋ ์๋ณธ์ ํผ์๋์ง ์๋๋ค.
๊ฐ์ฒด๋ฅผ ํ๋กํผํฐ ๊ฐ์ผ๋ก ๊ฐ๋ ๊ฐ์ฒด์ ๊ฒฝ์ฐ ์์ ๋ณต์ฌ๋ ํ ๋จ๊ณ๊น์ง๋ง ๋ณต์ฌํ๋ ๊ฒ์ ๋งํ๊ณ ๊น์ ๋ณต์ฌ๋ ๊ฐ์ฒด์ ์ค์ฒฉ๋์ด ์๋ ๊ฐ์ฒด๊น์ง ๋ชจ๋ ๋ณต์ฌํ๋ ๊ฒ์ ์๋ฏธํ๋ค. ์์ ๋ณต์ฌ์ ๊น์ ๋ณต์ฌ๋ก ์์ฑ๋ ๊ฐ์ฒด๋ ์๋ณธ๊ณผ๋ ๋ค๋ฅธ ๊ฐ์ฒด๋ค.
์์ ๋ณต์ฌ๋ฅผ ์ํด์๋ Spread Operator ๋๋ Object.assign์ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ๊น์ ๋ณต์ฌ๋ฅผ ํ๋ ค๋ฉด ์ฌ๊ทํจ์๋ฅผ ์ด์ฉํ๊ฑฐ๋ JSON ๋ณํ์ ์ฌ์ฉํ๋ฉด ๋๋ค.
๋ถ๋ณ๊ฐ์ธ ๊ธฐ๋ณธํ vs ๊ฐ๋ณ๊ฐ์ธ ์ฐธ์กฐํ
๊ธฐ๋ณธํ์ ๋ถ๋ณ๊ฐ์ด๋ค.
๊ธฐ๋ณธํ ํ์ ์ ๊ฒฝ์ฐ ๊ธฐ์กด์ ์ ์ธํด ๋์ ๋ณ์์ ์๋ก์ด ๊ฐ์ ํ ๋นํ๋ ค๋ฉด ๋ฐ์ดํฐ์ ์๋ก์ด ์์ญ์ ๋ง๋ จํด์, ํด๋น ๊ณต๊ฐ์ ์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ , ํด๋น ๋ฐ์ดํฐ์ ์ฃผ์๊ฐ์ ๋ค์ ๊ธฐ์กด์ ๋ณ์์ ํ ๋นํ๋ ์์ผ๋ก ์ด๋ฃจ์ด์ง๋ ๋ถ๋ณ๊ฐ์ด๋ค.
์๋ ์ฝ๋์์ a๋ ์ฒ์์๋ 'abc'๋ฅผ ๋ด๊ณ ์๋ ๋ฐ์ดํฐ ์์ญ์ ์ฃผ์๊ฐ @2001์ ๊ฐ์ง๊ณ ์๋ค๊ฐ, 'abcdef'๋ฅผ ๋ค์ ํ ๋นํ๋ฉด 'abcdef'๋ฅผ ๋ด๊ฒ ๋ ๊ณต๊ฐ์ ๋ง๋ค์ด ํด๋น ๊ณต๊ฐ์ ์ฃผ์๊ฐ์ธ @2002๋ฅผ a์ ์๋ก ํ ๋นํ๋ค.
// ๊ธฐ๋ณธํ ํ์ (primitive type)์ ๋ถ๋ณ์ฑ var a = 'abc'; a = a +'def'; // abc์ abcdef๋ ์ ํ ๋ค๋ฅธ ๋ฐ์ดํฐ ์์ญ์ ์ ์ฅ๋๋ค. (์๋ก ๋ง๋ค์ด์ง๋ค.) var b = 5; var c = 5; b = 7; // b๋ฅผ 7๋ก ๋ฐ๊พธ๋ฉด, ๊ธฐ์กด์ 7์ด ๋ค์ด์๋ ๋ฐ์ดํฐ ์์ญ ์๋์ง ๋จผ์ ๊ฒ์ฌ, // ์์ผ๋ฉด ์๋ก ๋ง๋ค์ด์ b์ ์ ์ฅํจ
[ ์ด๋ฆ : a / ๊ฐ : @2001('abc') ] => [ ์ด๋ฆ : a / ๊ฐ : @2002('abcdef') ] // ์ฃผ์๊ฐ์ด ์์ ๋ฌ๋ผ์ง๋ค.
[ ์ด๋ฆ : b / ๊ฐ : @3001(5) ] => [ ์ด๋ฆ : b / ๊ฐ : @3003(7) ]๋ฐ๋ฉด, ์ฐธ์กฐํ ํ์ ์ ๊ฐ๋ณ๊ฐ์ด๋ค.
์ด๋ค ๊ฐ์ฒด์ ํ๋กํผํฐ ๊ฐ์ ๋ณ๊ฒฝํ๋ค๊ณ ํด๋ณด์. ์๋ ์์ ์ฝ๋์์ obj1์ด๋ผ๋ ๊ฐ์ฒด๋ a์, b๋ฅผ ๋ด๊ณ ์๋ ๋ฐ์ดํฐ์ ์ฃผ์๊ฐ ๋ฌถ์์ ๊ฐ์ง๊ณ ์๊ฒ ๋๋ค. ๋ค์ ๋งํด, obj1์ a,b๊ฐ ์ ์ฅ๋์ด ์๋ ๋ฐ์ดํฐ์ ์ฃผ์๊ฐ @7103, @7104๋ฅผ ๊ฐ์ง๊ณ ์๋ ๋ฐ์ดํฐ์ ์ฃผ์๊ฐ @5001์ ๊ฐ์ง๊ณ ์๊ฒ ๋๋ค.
๋ง์ฝ ํ๋กํผํฐ a๋ฅผ ๋ณ๊ฒฝํ ๊ฒฝ์ฐ, a๊ฐ ์ ์ฅ๋์ด ์๋ ๋ฐ์ดํฐ์ ์ฃผ์๊ฐ์ธ @7103์ ์ฐพ์๊ฐ ํด๋น ๋ฐ์ดํฐ๊ฐ ๊ฐ์ง๊ณ ์๋ ๊ฐ์ ์ฃผ์๊ฐ์ ๋ณ๊ฒฝํด์ฃผ๋ ๋ฐฉ์์ผ๋ก ๊ฐ์ ๋ณ๊ฒฝํ๋ค. ์ด ๋, obj1์ด ๊ฐ์ง๊ณ ์๋ ๋ฐ์ดํฐ์ ์ฃผ์๊ฐ, ์ฆ @5001์ ๋ด๊ฒจ ์๋ ์ฃผ์๊ฐ์ ๊ทธ๋๋ก @7103, @7104์ด๋ฉฐ ๋จ์ง @7103์ ์ ์ฅ๋์ด ์๋ ๊ฐ์ ๋ณ๊ฒฝ(@5003 -> @5004)ํด ์ค ๋ฟ์ด๋ค.
์ฃผ๋ชฉํ ์ ์ ํ๋กํผํฐ ๋ณ๊ฒฝ ์ ๊ณผ ํ์ obj 1์ด ๊ฐ๋ฆฌํค๊ณ ์๋ ๋ฐ์ดํฐ์ ์ฃผ์๊ฐ @5001์ ๋ณํ์ง ์๋๋ค๋ ๊ฒ์ด๋ค. (cf. ๊ธฐ๋ณธํ์ ๊ฒฝ์ฐ ๊ฐ์ ๋ณ๊ฒฝํ๋ฉด ๊ฐ์ง๊ณ ์๋ ๋ฐ์ดํฐ์ ์ฃผ์๊ฐ ์์ฒด๊ฐ ๋ณํ๋ค.)
// ์ฐธ์กฐํ ํ์ (reference type)์ ๊ฐ๋ณ์ฑ - ํ๋กํผํฐ ์ฌํ ๋น var obj1 = { a: 1, b: 'bbb' }; obj1.a = 2; // obj1์ด ๊ฐ๋ฆฌํค๊ณ ์๋ ์ฃผ์๊ฐ์ ๋ด๊ณ ์๋ @5001(๋ฐ์ดํฐ @7103~@7104)์ ๋ณํ์ง ์๋๋ค. // @7103์์ ์๋ ๊ฐ์ด @5004๋ก ๋ฐ๋ ๋ฟ์ด๋ค.
๋ณ๊ฒฝ ์
[ ์ด๋ฆ : obj1 / ๊ฐ : @5001(@7103(@5003(1)) ~ @7104(@5002(bbb)) ]๋ณ๊ฒฝ ํ
[ ์ด๋ฆ : obj1 / ๊ฐ : @5001(@7103(@5004(2)) ~ @7104(@5002(bbb)) ]*๋ณ๊ฒฝ ์ ๊ณผ ํ์ obj1์ ๋์ผํ๊ฒ @5001(@7103~ @7104)์ ๊ฐ์ผ๋ก ๊ฐ์ง๊ณ ์๋ค.
๊ฐ๋ณ์ฑ์ด ๋ณต์ฌ์ ๋ฏธ์น๋ ์ํฅ
์์ ์ค๋ช ํ ๊ฒ๊ณผ ๊ฐ์ ์ด์ ๋ก, ๋ณต์ฌ๋ฅผ ํ๊ฒ ๋๋ฉด ๊ธฐ๋ณธํ ํ์ ์ ๊ฐ์ด ๋ด๊ธด ์ฃผ์๊ฐ์ ๋ฐ๋ก ๋ณต์ ํ๋ ๋ฐ๋ฉด, ์ฐธ์กฐํ์ ๊ฐ์ด ๋ด๊ธด ์ฃผ์๊ฐ๋ค๋ก ์ด๋ฃจ์ด์ง ๋ฌถ์์ ๊ฐ๋ฆฌํค๋ ์ฃผ์๊ฐ์ ๋ณต์ ํ๋ค. ๋ค์, ์ฃผ๋ชฉํด์ผ ํ ์ ์
์ฐธ์กฐํ์ ์ฃผ์๊ฐ์ ๋ณต์ ํ๋ค
๋ผ๋ ๊ฒ์ด๋ค.์ฐธ์กฐํ์ ์ฃผ์๊ฐ์ ๋ณต์ ํ๋ค๋ ํน์ฑ ๋๋ฌธ์ ์ฐธ์กฐํ์์
๋ณต์ฌ
๋ ๋ค์์ ๊ฐ์ด ๋ ๊ฐ์ง๋ก ๋๋์ด์ง๋ค.๋ถ๋ฅ ์ ์ ์ค๋ช ์์ ๋ณต์ฌ(shallow copy) ๋ฐ๋ก ์๋ ๋จ๊ณ์ ๊ฐ๋ง ๋ณต์ฌ ์ค์ฒฉ๊ฐ์ฒด์์ ์ฐธ์กฐํ ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋ ํ๋กํผํฐ๋ฅผ ๋ณต์ฌํ ๋ ๊ทธ ์ฃผ์๊ฐ๋ง ๋ณต์ฌ. ์ฆ, ์ฌ๋ณธ ๋ฐ๊พธ๋ฉด ์๋ณธ์ ๋ฐ์ดํฐ๋ ๋ฐ๋ ๊น์ ๋ณต์ฌ(deep copy) ๋ด๋ถ์ ๋ชจ๋ ๊ฐ๋ค์ ํ๋ํ๋ ์ ๋ถ ์ฐพ์์ ๋ณต์ฌ ๋ชจ๋ ๋ณต์ฌํ๋ฏ๋ก ์๋ณธ์ ๋ถ๋ณ์ฑ ์ ์ง๊ฐ๋ฅ ์์ ๋ณต์ฌ๋?
์ฐธ์กฐ๊ฐ์ ๋ณต์ฌํ๋ ๊ฒ์ ์๋ฏธํ๋ค. ๋ณต์ฌ๋ณธ์ ๋ณ๊ฒฝํ๋ฉด ์๋ณธ์ด ๋ณ๊ฒฝ๋๋ค.
var obj1 = { c: 10, d: 'ddd'}; var obj2 = obj1; // obj2์ obj1์ ์ฃผ์๊ฐ์ ๋ณต์ฌ obj2 = { c: 20, d: 'ddd'}; // ์ฃผ์๊ฐ์ ๋ณต์ฌํ๊ธฐ ๋๋ฌธ์ ๋ณต์ฌํ ๊ฐ์ฒด์ ํ๋กํผํฐ๋ฅผ ๋ณ๊ฒฝํ๋ฉด ์๋ณธ๋ ๋ณ๊ฒฝ๋๋ค.
์์ ๋ณต์ฌ์ ๋ฐฉ๋ฒ์ผ๋ก Spread Operator ํน์ Object.assign์ ์ด์ฉํ๋ค.
๊ทธ๋ฐ๋ฐ ์ธํฐ๋ท์ ์ฐพ๋ค๋ณด๋ฉด Spread Operator๋ 1depth๊น์ง ๊น์ ๋ณต์ฌ๋ค ๋ผ๋ ๊ธ์ ๋ง์ด ์ฐพ์ ์ ์์ด์ ์ฒ์์๋ ํท๊ฐ๋ ธ๋ค. ๋์ ๊ฒฝ์ฐ [ ], { } ๋ฐฐ์ด ๋ฆฌํฐ๋ด, ๊ฐ์ฒด๋ฆฌํฐ๋ด์ด ์คํ๋ ๋ ์ฐ์ฐ์์ ํ ๋ถ๋ถ์ด๋ผ๊ณ ์ฎ์ด์ ์๊ฐํ์ฌ ์คํ๋ ๋ ์ฐ์ฐ์๋ฅผ ์ด์ฉํด ์์ ๋ณต์ฌ๋ฅผ ํ๋ค๋ ๋ง์ด ์ ์ดํด๊ฐ ๊ฐ์ง ์์๋ค.
์ ๋ฆฌํด ๋ณด์๋ฉด, { ...obj }์ ๊ฐ์ด ์ด๋ค ๊ฐ์ฒด๋ฅผ ์คํ๋ ๋ ์ฐ์ฐ์๋ก ๋ณต์ฌํ ๋, { } ์ค๊ดํธ ๋ถ๋ถ์ ๊ฐ์ฒด ๋ฆฌํฐ๋ด๋ก ์๋ก์ด ์ฃผ์๊ฐ์ ๋ง๋ค์ด ๋ด๋ฉฐ, ์คํ๋ ๋ ์ฐ์ฐ์๋ก ๊ฐ์ ๋ณต์ฌํด ์จ๋ค. ์ด ๋, ์๋ณธ์ ๊ฐ์ด ์์ํ(primitive type)์ธ์ง, ์ฐธ์กฐํ(reference type)์ธ์ง์ ๋ฐ๋ผ ๊ฐ์ ๋ณต์ฌํ๋๋, ์ฃผ์๊ฐ์ ๋ณต์ฌํ๋๋๊ฐ ๋๋๋ค. ์ฐธ์กฐํ์ ๊ฒฝ์ฐ ์ฐธ์กฐํ ์์ ํ๋กํผํฐ๊น์ง ์ ๋ถ ๋ณต์ฌํ์ง ์๊ณ ์ฃผ์๊ฐ๋ง ๋ณต์ฌ๊ฐ ๋์์ผ๋ฏ๋ก, ๋ณต์ฌํ ๊ฐ์ฒด์ ์ฐธ์กฐํ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ฉด ์๋ณธ๋ ๋ณ๊ฒฝ์ด ๋๋ค.
๋ฐ๋ผ์ ์์ ๋ณต์ฌ์ด๋ฉฐ, ์ฐธ์กฐํ ๋ฐ์ดํฐ๊น์ง ์ฐธ์กฐ๋ฅผ ๋์ด์ฃผ๋๋ก ์์ ํ ๋ณต์ฌ๋ฅผ ํ๋ ๊ฒ์ ๊น์ ๋ณต์ฌ๋ผ๊ณ ํ๋ ๊ฒ์ด๋ค.์์ ๋ณต์ฌ 1. Spread Operator
const obj = {name: 'Minju', favorites:{food:'cake', music: 'acoustic'}}; const copyObj = {...obj} // { }๊ฐ์ฒด๋ฆฌํฐ๋ด๋ก ์๋ก์ด ๊ฐ์ฒด ๋ง๋ ํ, name์ ๊ฐ ๋ณต์ฌ, favorites๋ ์ฃผ์๊ฐ ๋ณต์ฌ copyObj.name = 'Ariel'; // primitive type์ด๊ธฐ ๋๋ฌธ์ ์๋ณธ ๋ฐ๋์ง ์์. copyObj.favorites.food = 'bread' // obj.favorites์ copyObj.favorites๋ ๊ฐ์ ์ฃผ์๊ฐ์ ๊ฐ์ง๊ณ ์์๋๋ฐ, ๊ทธ ์ค copyObj์ food์ ๋ค์ด์๋ ๊ฐ์ ๋ณ๊ฒฝํ์ผ๋, obj๋ ๋ฉ๋ฌ์ ๋ณ๊ฒฝ๋จ
์์ ๋ณต์ฌ 2. Object.assign()
Spread Operator ๋์ ์ Object.assign()์ ์ด์ฉํด๋ ๋๋ค.
const obj = {a : 1, b: 2} const copyObj = Object.assign({}, obj) // ์ต์๋จ์ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ์ฃผ์๊ฐ์ด ์์ ๋ฌ๋ผ์ก์ง๋ง, ๋ด๋ถ์ ๊ฐ์ ๊ทธ๋๋ก ๋ณต์ฌํด ์ด
๊น์ ๋ณต์ฌ๋?
๋ด๋ถ์ ๋ชจ๋ ๊ฐ๋ค์ ํ๋ํ๋ ์ ๋ถ ์ฐพ์์ ๋ณต์ฌํ์ฌ ์์
์๋ก์ด ๊ฐ์ฒด
๋ฅผ ๋ง๋๋ ๊ฒ์ ์๋ฏธํ๋ค.๊ฐ์ ๊ฐ์ง๋ง ์์ํ, ์ฐธ์กฐํ์ ์๊ด์์ด ์ฃผ์๊ฐ์ด ์์ ํ ๋ค๋ฅธ, ์ ํ ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ํ๋ ๋ง๋๋ ๊ฒ์ด๋ค. ์์ ๋ณต์ฌ์ ๋ค๋ฅด๊ฒ ๋ณต์ฌ๋ณธ ๋ณ๊ฒฝ์ ์๋ณธ์ ์ ์ง๋๋ค.
๊ฐ์ผ๋ก ์ ๋ฌ๋ฐ์ ๊ฐ์ฒด์ ๋ณ๊ฒฝ์ ๊ฐํ๋๋ผ๋ ์๋ณธ ๊ฐ์ฒด๋ ๋ณํ์ง ์์์ผ ํ๋ ๊ฒฝ์ฐ ์ฌ์ฉํ๋ค. ๊น์ ๋ณต์ฌ๋ฅผ ํ๋ ค๋ฉด ์ฌ๊ทํจ์๋ฅผ ์ฌ์ฉํ๊ฑฐ๋, JSON ๋ณํ์ ํ๋ฉด ๋๋ค.
๊น์ ๋ณต์ฌ ๋ฐฉ๋ฒ 1. ์ฌ๊ทํจ์ ์ฌ์ฉ
var copyObjectDeep = function(target){ var result = {}; if(typeof target === 'object' && target !== null){ // typeof ๋ช ๋ น์ด๊ฐ null์ ๋ํด์๋ 'object'๋ฅผ ๋ฐํํ๊ธฐ ๋๋ฌธ์ ์กฐ๊ฑด์ ์ถ๊ฐํจ for (var prop in target){ result[prop] = copyObjectDeep(target[prop]); // ๊ฐ์ฒด์ธ ๊ฒฝ์ฐ ์ฌ๊ท์ ์ผ๋ก ํธ์ถ } }else{ result = target; } return result; }
๊น์ ๋ณต์ฌ ๋ฐฉ๋ฒ 2. JSON ๋ณํ ์ฌ์ฉ
๊ฐ์ฒด๋ฅผ JSON ๋ฌธ๋ฒ์ผ๋ก ํํ๋ ๋ฌธ์์ด๋ก ์ ํํ๋ค๊ฐ ๋ค์ JSON ๊ฐ์ฒด๋ก ๋ฐ๊พธ๋ฉด ๊น์ ๋ณต์ฌ๋ฅผ ํ ์ ์๋ค.
httpRequest๋ก ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ๊ฐ์ฒด๋ฅผ ๋ณต์ฌํ ๋ ๋ฑ ์์ํ ์ ๋ณด๋ง ๋ค๋ฃฐ ๋ ํ์ฉํ๊ธฐ ์ข์ ๋ฐฉ๋ฒ์ด๋ค!var copyObjectViaJSON = function(target) { return JSON.parse(JSON.stringify(target)); };