Explaining Value vs Reference in Javascript - Lee-hyuna/33-js-concepts-kr GitHub Wiki

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ์˜ ๊ฐ’(value) vs ์ฐธ์กฐ (Reference)

(์ปดํ“จํ„ฐ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๋ฌด์Šจ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€ ๊ฐ„๋‹จํžˆ ์‚ดํŽด๋ณด์ž.)

์ด ๊ธฐ์‚ฌ๋Š” ์˜จ๋ผ์ธ ์ฝ”์Šค์ธ Step Up Your JS: A Comprehensive Guide to Intermediate JavaScript์—์„œ ๊ฐ€์ง€๊ณ  ์™”๋‹ค. ๋Œ€ํ™”์‹ ์ฝ”๋“œ ๊ณต๊ฐ„(๋†€์ดํ„ฐ)๊ณผ ์˜จ๋ผ์ธ ํ€ด์ฆˆ๋ฅผ ์œ„ํ•ด ๋ฌด๋ฃŒ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. (์ฐธ๊ณ  : ๋ฌด๋ฃŒ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋Š” ๋งํฌ)

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๊ฐ’์„ ์ „๋‹ฌํ•˜๋Š” Boolean, null, undefined, String, Number 5๊ฐ€์ง€ ํƒ€์ž…์„ ๊ฐ€์ง„๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๋ฅผ Primitive Type์ด๋ผํ•œ๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์ฐธ์กฐ(Reference)์„ ์ „๋‹ฌํ•˜๋Š” Array, Function ๊ทธ๋ฆฌ๊ณ  Object 3๊ฐ€์ง€ ํƒ€์ž…์„ ๊ฐ€์ง„๋‹ค. ์ด๊ฒƒ์€ ๋ชจ๋‘ ๊ธฐ์ˆ ์ ์œผ๋กœ Object์ด๊ณ , ๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ๋“ค์„ Object์˜ ๋ชจ์Œ์ด๋ผ ์–ธ๊ธ‰ํ•œ๋‹ค.

Primitives

๋งŒ์•ฝ Primitive ํƒ€์ž…์ด ๋ณ€์ˆ˜์— ํ• ๋‹น๋˜๋ฉด, ํ•ด๋‹น ๋ณ€์ˆ˜๊ฐ€ primitive ๊ฐ’์„ ํฌํ•จํ•œ ๋ณ€์ˆ˜๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

var x = 10;
var y = 'abc';
var z = null;

x๋Š” 10์„ ํฌํ•จ, y๋Š” 'abc'๋ฅผ ํฌํ•จํ•œ๋‹ค. ์ด ์•„์ด๋””์–ด๋ฅผ ํ™•๊ณ ํžˆ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์šฐ๋ฆฌ๋Š” ์ด ๋ณ€์ˆ˜๋“ค๊ณผ ๊ฐ๊ฐ์˜ ๊ฐ’๋“ค์ด ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์–ด๋–ป๊ฒŒ ๋ณด์ด๋Š”์ง€์— ๋Œ€ํ•œ ์ด๋ฏธ์ง€๋ฅผ ์œ ์ง€ํ•  ๊ฒƒ์ด๋‹ค.

์šฐ๋ฆฌ๋Š” =์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋“ค ๋ณ€์ˆ˜์— ๋‹ค๋ฅธ ๋ณ€์ˆ˜๋ฅผ ํ• ๋‹นํ•  ๋•Œ, ์šฐ๋ฆฌ๋Š” ์ƒˆ๋กœ์šด ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ๋ณต์‚ฌํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ๋Š” ๊ฐ’์„ ๋ณต์‚ฌํ•œ๋‹ค.

var x = 10;
var y = 'abc';
var a = x;
var b = y;
console.log(x, y, a, b); // -> 10, 'abc', 10, 'abc'

a์™€ x์— 10์„ ๋ชจ๋‘ ํฌํ•จํ•œ๋‹ค. b์™€ y๋Š” 'abc'๋ฅผ ํฌํ•จํ•œ๋‹ค. ๊ทธ๋“ค์€ ๊ฐ’์ด ๋ณต์‚ฌ ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ๊ฐ์˜ ๋ณ€์ˆ˜์— ๊ฐ’์„ ๊ฐ€์ง„๋‹ค.

ํ•˜๋‚˜๋ฅผ ๋ฐ”๊พผ ๋‹ค๊ณ ํ•ด์„œ ๋‹ค๋ฅธ ๊ฒƒ์ด ๋ฐ”๋€Œ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ๋ณ€์ˆ˜๋“ค์ด ์„œ๋กœ ๊ด€๊ณ„๊ฐ€ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ด์•ผํ•œ๋‹ค.

var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'

Objects

์ด๊ฒƒ์€ ํ˜ผ๋ž€์Šค๋Ÿฝ๊ฒ ์ง€๋งŒ, ์ฐธ๊ณ  ๋๊นŒ์ง€ ์ฝ์–ด๋ผ. ์ผ๋‹จ ์ด๊ฒจ๋‚ด๋ฉด ์‰ฌ์›Œ ๋ณด์ผ ๊ฒƒ์ด๋‹ค.

๊ธฐ๋ณธ ๊ฐ’์ด ์•„๋‹Œ ํ• ๋‹น๋œ ๋ณ€์ˆ˜์—๋Š” ํ•ด๋‹น ๊ฐ’์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ์ œ๊ณต๋œ๋‹ค. ๊ทธ ์ฐธ์กฐ๋Š” ๋ฉ”๋ชจ๋ฆฌ์—์„œ Object์˜ ์œ„์น˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋‹ค. ๋ณ€์ˆ˜์—๋Š” ์‹ค์ œ๋กœ ๊ฐ’์ด ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค. 

Object๋Š” ์ปดํ“จํ„ฐ ๋ฉ”๋ชจ๋ฆฌ์˜ ์ผ๋ถ€ ์œ„์น˜์— ์ƒ์„ฑ๋œ๋‹ค. arr = [] ์„ ์ž‘์„ฑ ํ–ˆ์„ ๋•Œ, ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•œ๋‹ค. arr ๋ณ€์ˆ˜๋Š” ๋ฐฐ์—ด์˜ ์ฃผ์†Œ, ์œ„์น˜๋ฅผ ๋ฐ›๋Š”๋‹ค.

์ฃผ์†Œ๊ฐ€ ์ˆซ์ž๋‚˜ ๋ฌธ์ž์—ด ์ฒ˜๋Ÿผ ๊ฐ’์œผ๋กœ ์ „๋‹ฌ๋˜๋Š” ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ ์œ ํ˜•์ด๋ผ๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. ์ฃผ์†Œ๋Š” ์ฐธ์กฐ์— ์˜ํ•ด ์ „๋‹ฌ๋˜๋Š” ๊ฐ’์˜ ์œ„์น˜, ๋ฉ”๋ชจ๋ฆฌ ์œ„์น˜๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค. ๋ฌธ์ž์—ด์ด ๋”ฐ์˜ดํ‘œ('' ๋˜๋Š” "")๋กœ ํ‘œ๊ธฐ๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ์ฃผ์†Œ๋Š” ํ™”์‚ดํ‘œ ๊ด„ํ˜ธ์ธ <>๋กœ ํ‘œ๊ธฐ๋œ๋‹ค.

์ฐธ์กฐ ํƒ€์ž… ๋ณ€์ˆ˜๋ฅผ ํ• ๋‹นํ•˜๊ณ  ์‚ฌ์šฉํ•  ๋•Œ ์ž‘์„ฑํ•˜๊ณ  ๋ณด๋Š” ๋‚ด์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

1) var arr = [];
2) arr.push(1);

๋ฉ”๋ชจ๋ฆฌ์—์„œ 1, 2 ๋ผ์ธ์„ ํ‘œํ˜„ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

์ด ๋ณ€์ˆ˜ arr์€ ๊ฐ’์„ ํฌํ•จํ•˜๊ณ , ์ฃผ์†Œ๋Š” ์ •์ ์ž„์„ ์œ ์˜ํ•˜๋ผ. ๋ฐฐ์—ด์€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๋ณ€ํ•œ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ๊ฐ’์„ pushํ•˜๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ ๊ฐ™๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ arr์„ ์‚ฌ์šฉ ํ•  ๋•Œ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ ๋ฉ”๋ชจ๋ฆฌ์— ์žˆ๋Š” arr์˜ ์œ„์น˜๋กœ ๊ฐ€์„œ ๊ทธ ๊ณณ์— ์žˆ๋Š” ์ €์žฅ๋œ ์ •๋ณด๋กœ ์ผ์„ ํ•˜๊ฒŒ ํ•œ๋‹ค.

์ฐธ์กฐ์— ์˜ํ•œ ํ• ๋‹น (Assigning by Reference)

์ฐธ์กฐ ์œ ํ˜• ๊ฐ’, ์ฆ‰ object์— =์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ๋ณ€์ˆ˜์— ๋ณต์‚ฌํ•  ๋•Œ, ๊ทธ ๊ฐ’์˜ ์ฃผ์†Œ๋Š” ์‹ค์ œ๋กœ primitive ์ฒ˜๋Ÿผ ๋ณต์‚ฌ๋˜๋Š” ๊ฒƒ์ด๋‹ค. object๋Š” ๊ฐ’ ๋Œ€์‹  ์ฐธ์กฐ๋กœ ๋ณต์‚ฌ๋œ๋‹ค.

var reference = [1];
var refCopy = reference;

์œ„์˜ ์ฝ”๋“œ๋Š” ๋ฉ”๋ชจ๋ฆฌ์—์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋ณด์—ฌ์ง„๋‹ค.

๊ฐ ๊ฐ์˜ ๋ณ€์ˆ˜๋Š” ์ง€๊ธˆ ๊ฐ™์€ ๋ฐฐ์—ด์˜ ์ฐธ์กฐ๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋‹ค. ์ด ๋œป์€ ๋งŒ์•ฝ reference๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด retCopy์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

reference.push(2);
console.log(reference, refCopy); // -> [1, 2], [1, 2]

2๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— pushํ•˜๊ณ , reference์™€ refCopy๊ฐ€ ์‚ฌ์šฉ๋  ๋•Œ ๊ฐ™์€ ๋ฐฐ์—ด์„ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋‹ค.

์ฐธ์กฐ ์žฌํ• ๋‹น (Reassigning a Reference)

๊ธฐ์ค€์ด ๋˜๋Š” ๋ณ€์ˆ˜๋ฅผ ์žฌํ• ๋‹นํ•˜๋ฉด ๊ธฐ์กด ์ฐธ์กฐ๊ฐ€ ๋Œ€์ฒด ๋œ๋‹ค.

var obj = { first: 'reference' };

์ด๊ฒƒ์€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ

๋‘๋ฒˆ์งธ ๋ผ์ธ์„ ์ถ”๊ฐ€ํ•˜๋ฉด

var obj = { first: 'reference' };
obj = { second: 'ref2' }

์ฃผ์†Œ๋Š” obj ๋ณ€๊ฒฝ์‚ฌํ•ญ์— ์˜ํ•ด ์ €์žฅ์ด ๋œ๋‹ค. first object๋Š” ์—ฌ์ „ํžˆ ๋ฉ”๋ชจ๋ฆฌ์— ์กด์žฌํ•˜๋ฉฐ, ๊ทธ ๋‹ค์Œ object๋„ ๋™์ผํ•˜๋‹ค.

์œ„์˜ ์ฃผ์†Œ #234์—์„œ ๋ณด๋“ฏ์ด object์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ๋‚จ์•„์žˆ์ง€ ์•Š์„ ๋•Œ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ garbage collection์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ๊ฒƒ์€ ๋‹จ์ง€ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๊ทธ object์— ๋Œ€ํ•œ ๋ชจ๋“  ์ฐธ์กฐ๋ฅผ ์žƒ์–ด๋ฒ„๋ ค์„œ ๊ทธ object๋ฅผ ๋” ์ด์ƒ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๋ฏ€๋กœ, ์—”์ง„์€ ๊ณ„์†ํ•ด์„œ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์•ˆ์ „ํ•˜๊ฒŒ ์‚ญ์ œ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ๊ฒฝ์šฐ {first:'reference'}๋Š” ๋” ์ด์ƒ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์—†์œผ๋ฉฐ ์—”์ง„์—์„œ garbage collection์„ ์œ„ํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

== ๊ทธ๋ฆฌ๊ณ  ===

์ผ์น˜ ์—ฐ์‚ฐ์ž == ๊ทธ๋ฆฌ๊ณ  === ์€ ๊ฐ’๊ณผ ํƒ€์ž…, ์ฐธ์กฐ๋ฅผ ํ™•์ธํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. ๋งŒ์•ฝ ๋ณ€์ˆ˜๊ฐ€ ๊ฐ™์€ ์•„์ดํ…œ์˜ ์ฐธ์กฐ๋ฅผ ํฌํ•จํ•œ๋‹ค๋ฉด, ๊ทธ ๋น„๊ต์˜ ๊ฒฐ๊ณผ๋Š” true์ด๋‹ค.

var arrRef = [โ€™Hi!โ€™];
var arrRef2 = arrRef;
console.log(arrRef === arrRef2); // -> true

๋งŒ์•ฝ ๊ตฌ๋ณ„์ด ๋˜๋Š” ojbect๋ผ๋ฉด ๋น„๋ก ๋™์ผํ•œ porperty๋“ค์„ ํฌํ•จํ•˜๊ณ  ์žˆ๋”๋ผ๋„ ๋น„๊ต ๊ฒฐ๊ณผ๋Š” false์ด๋‹ค.

var arr1 = ['Hi!'];
var arr2 = ['Hi!'];
console.log(arr1 === arr2); // -> false

๋งŒ์•ฝ ๋‘ ๊ฐœ๊ฐ€ ๊ตฌ๋ณ„์ด ๋˜๋Š” object๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ๊ทธ property๊ฐ€ ๊ฐ™์€์ง€ ์•Œ์•„๋ณด๋ ค๊ณ  ํ•œ๋‹ค๋ฉด, ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ ๋‘˜๋‹ค string์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ๋‚œ ๋‹ค์Œ ๋น„๊ต ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ผ์น˜ ์—ฐ์‚ฐ์ž๊ฐ€ primitive์„ ๋น„๊ตํ•  ๋•Œ, ๋‹จ์ˆœํžˆ ๊ฐ’์ด ๊ฐ™์€์ง€ ํ™•์ธํ•œ๋‹ค.

var arr1str = JSON.stringify(arr1);
var arr2str = JSON.stringify(arr2);
console.log(arr1str === arr2str); // true

๋˜ ๋‹ค๋ฅธ ์˜ต์…˜์€ ojbect ์‚ฌ์ด๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ˆœํ™˜ํ•˜์—ฌ ๊ฐ ์†์„ฑ์ด ๋™์ผํ•œ์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

ํ•จ์ˆ˜๋ฅผ ํ†ตํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ ์ „๋‹ฌ

ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ primitive ๊ฐ’์„ ์ „๋‹ฌํ•  ๋•Œ, ํ•จ์ˆ˜๋Š” ๊ฐ’์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ณต์‚ฌํ•œ๋‹ค. ์ด๊ฒƒ์€ =์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ์‚ฌ์‹ค์ƒ ๊ฐ™๋‹ค.

var hundred = 100;
var two = 2;
function multiply(x, y) {
    // PAUSE
    return x * y;
}
var twoHundred = multiply(hundred, two);

์œ„์˜ ์˜ˆ์ œ์—์„œ, hundred์˜ ๊ฐ’์€ 100์ด๋‹ค. hundred๊ฐ€ multiply๋กœ ์ „๋‹ฌ๋˜์–ด ๋ณ€์ˆ˜ x ๊ฐ€ ๊ทธ ๊ฐ’์„ 100์œผ๋กœ ์–ป๋Š”๋‹ค. ์ด ๊ฐ’์€ ๋งˆ์น˜ =์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ’์ด ๋ณต์‚ฌ ๋˜์–ด์กŒ๋‹ค. ๋‹ค์‹œ ๋งํ•˜์ง€๋งŒ, hundred์˜ ๊ฐ’์€ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค. multiply ํ•จ์ˆ˜ ์•ˆ์˜ PAUSE ์ฃผ์„์—์„œ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ๋Š”์ง€ ๋ณด์—ฌ์ฃผ๋Š” ์Šค๋ƒ…์ƒท์ด ์žˆ๋‹ค. (Here is a snapshot of what the memory looks like right at the PAUSE comment line in multiply.)

์ˆœ์ˆ˜ ํ•จ์ˆ˜(Pure Function)

์šฐ๋ฆฌ๋Š” ์™ธ๋ถ€ scope์—์„œ ์•„๋ฌด๋Ÿฐ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๋Š” ํ•จ์ˆ˜๋ฅผ pure Function์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. ํ•จ์ˆ˜๊ฐ€ primitive ๊ฐ’๋งŒ์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ํ•˜๊ณ , ๊ทธ ์ฃผ๋ณ€ scope์— ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ํ•œ, ์™ธ๋ถ€ scope์˜ ์–ด๋–ค ๊ฒƒ๋„ ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ž๋™์ ์œผ๋กœ pureํ•ด์ง„๋‹ค. ๋‚ด๋ถ€์—์„œ ์ƒ์„ฑ๋œ ๋ชจ๋“  ๋ณ€์ˆ˜๋Š” ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜๋˜๋Š” ์ฆ‰์‹œ garbage-colledted ํ•ด์ง„๋‹ค.

์ฐธ๊ณ 

๊ทธ๋Ÿฌ๋‚˜ object๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ํ•จ์ˆ˜๋Š” ์ฃผ๋ณ€ scope์˜ ์ƒํƒœ๋ฅผ ๋ณ€ํ˜•์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ ํ•จ์ˆ˜๊ฐ€ Array ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์™€์„œ ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ฐฐ์—ด์„ ๋ณ€๊ฒฝํ•œ ๊ฒฝ์šฐ, ํ•ด๋‹น ๋ฐฐ์—ด์„ ์ฐธ์กฐํ•˜๋Š” ๋ฒ”์œ„์˜ ๋ณ€์ˆ˜๋Š” ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ํ•œ๋‹ค. ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜๋œ ํ›„, ์™ธ๋ถ€ scope์—์„œ ๊ณ„์† ์œ ์ง€๋œ๋‹ค. ์ด๊ฒƒ์€ ์ถ”์ ์ด ์–ด๋ ค์šธ ์ˆ˜ ์žˆ๋Š” side effect๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ Array.map๊ณผ Array.filter๋ฅผ ํฌํ•จํ•œ ๋งŽ์€ native array ํ•จ์ˆ˜๋Š” pure function์œผ๋กœ ์“ฐ์—ฌ์ง„๋‹ค. ๊ทธ๋“ค์€ array ์ฐธ์กฐ๋ฅผ ๋ณต์‚ฌํ•˜๊ณ , ์›๋ณธ ๋Œ€์‹  ๋ณต์‚ฌ๋ณธ์œผ๋กœ ์ž‘์—…ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์›๋ณธ์€ ๊ทธ๋Œ€๋กœ, ์™ธ๋ถ€ scope๋Š” ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๊ณ , ์ƒˆ๋กœ์šด array์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ๋ฐ˜ํ™˜๋œ๋‹ค.

pure vs์™€ impure function์˜ ์˜ˆ๋ฅผ ๋ณด์ž.

function changeAgeImpure(person) {
    person.age = 25;
    return person;
}
var alex = {
    name: 'Alex',
    age: 30
};
var changedAlex = changeAgeImpure(alex);
console.log(alex); // -> { name: 'Alex', age: 25 }
console.log(changedAlex); // -> { name: 'Alex', age: 25 }

์ด impure function์€ ์–ด๋–ค object๋ฅผ ๊ฐ€์ง€๊ณ , object์˜ age์„ 25๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค. ์ด๋Š” ์ฐธ์กฐ์— ๋”ฐ๋ผ ์ž‘์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— alex object๋ฅผ ์ง์ ‘์ ์œผ๋กœ ๋ณ€ํ™” ์‹œํ‚จ๋‹ค. person ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ, ์ „๋‹ฌ๋œ object์™€ ์ •ํ™•ํžˆ ๋™์ผํ•œ object๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•ด๋ผ. alex์™€ alexChanged๋Š” (์ฝ”๋“œ๋กœ ๋ดค์„ ๋•Œ๋Š” changedAlex๊ฐ™์€๋ฐ ...์—ฌํŠผ..)๋Š” ๋™์ผํ•œ ์ฐธ์กฐ๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋‹ค. person๋ณ€์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ฐธ์กฐ๋ฅผ ์ƒˆ ๋ณ€์ˆ˜์— ์ €์žฅํ•˜๋Š” ๊ฒƒ์€ ์ค‘๋ณต์ด๋‹ค.

pureํ•œ ํ•จ์ˆ˜๋ฅผ ๋ณด์ž.

function changeAgePure(person) {
    var newPersonObj = JSON.parse(JSON.stringify(person));
    newPersonObj.age = 25;
    return newPersonObj;
}
var alex = {
    name: 'Alex',
    age: 30
};
var alexChanged = changeAgePure(alex);
console.log(alex); // -> { name: 'Alex', age: 30 }
console.log(alexChanged); // -> { name: 'Alex', age: 25 }

์ด ํ•จ์ˆ˜์—์„œ JSON.stringify๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ object๋ฅผ ๋ฌธ์ž์—ด๋กœ ๋ฐ˜ํ™˜ํ•œ ๋‹ค์Œ, ๋‹ค์‹œ JSON.parse๋กœ object๋ฅผ ํŒŒ์‹ฑํ•œ๋‹ค. ์ด ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ƒˆ๋กœ์šด ๋ณ€์ˆ˜์— ์ €์žฅํ•จ์œผ๋กœ์จ ์šฐ๋ฆฌ๋Š” ์ƒˆ๋กœ์šด object๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค. ์›๋ž˜์˜ object๋ฅผ ๋ฐ˜๋ณตํ•˜๊ณ  ๊ฐ๊ฐ์˜ ์†์„ฑ์„ ์ƒˆ๋กœ์šด ๊ฐ์ฒด์— ํ• ๋‹นํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ด ์žˆ์ง€๋งŒ, ์ด ๋ฐฉ๋ฒ•์€ ๊ฐ„๋‹จํ•˜๋‹ค. ์ƒˆ๋กœ์šด object๋Š” ์›๋ž˜ object์™€ ๊ฐ™์€ property๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋งŒ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๊ฐ๊ฐ ๋ถ„๋ฆฌ๋œ object์ด๋‹ค.

์ด ์ƒˆ๋กœ์šด object์—์„œ age์†์„ฑ์„ ๋ฐ”๊พธ๋ฉด ์›๋ณธ์€ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ์ด์ œ pureํ•ด์กŒ๋‹ค. ์ด๊ฒƒ์€ ์ž์‹ ์˜ scope ๋ฐ–์˜ ์–ด๋–ค object๋„ ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์—†๊ณ , ์‹ฌ์ง€์–ด ์ „๋‹ฌ๋œ object๋„ ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์—†๋‹ค. ์ƒˆ๋กœ์šด object๋Š” ๋ฐ˜ํ™˜๋˜๊ณ  ์ƒˆ๋กœ์šด ๋ณ€์ˆ˜์— ์ €์žฅ ๋˜์–ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋” ์ด์ƒ scope์— ํฌํ•จ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํ•จ์ˆ˜๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด garbage collected๋˜์–ด ์ง„๋‹ค.

ํ…Œ์ŠคํŠธ

Value์™€ reference๋Š” ์ฝ”๋”ฉ ์ธํ„ฐ๋ทฐ์—์„œ ์‹œํ—˜์ด ๋˜์–ด์ง„ ๊ฐœ๋…์ด๋‹ค. ์š”๊ธฐ์—์„œ ๋ฌด์—‡์ด ๊ธฐ๋ก์ด ๋˜์—ˆ๋Š”์ง€ ์Šค์Šค๋กœ ์•Œ์•„๋‚ด๋„๋ก ๋…ธ๋ ฅํ•ด๋ณด๋ผ.

function changeAgeAndReference(person) {
    person.age = 25;
    person = {
        name: 'John',
        age: 50
    };
    
    return person;
}
var personObj1 = {
    name: 'Alex',
    age: 30
};
var personObj2 = changeAgeAndReference(personObj1);
console.log(personObj1); // -> ?
console.log(personObj2); // -> ?

์ด ํ•จ์ˆ˜๋Š” ๋จผ์ € ์ „๋‹ฌ๋œ ์›๋ž˜์˜ object์— ๋Œ€ํ•œ age property๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค. ๊ทธ ๋‹ค์Œ ๋ณ€์ˆ˜๋ฅผ ์ƒˆ object์— ์žฌํ• ๋‹นํ•˜์—ฌ object๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์—ฌ๊ธฐ ๋‘ object๊ฐ€ logout๋œ ๋‚ด์šฉ์ด ์žˆ๋‹ค.

console.log(personObj1); // -> { name: 'Alex', age: 25 }
console.log(personObj2); // -> { name: 'John', age: 50 }

ํ•จ์ˆ˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ†ตํ•œ ํ• ๋‹น์€ =์œผ๋กœ ํ• ๋‹น ๋˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•˜๋ผ. ํ•จ์ˆ˜์—์„œ person๋ณ€์ˆ˜๋Š” personObj1์„ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ์„ ํฌํ•จํ•˜๊ณ  ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ฒ˜์Œ์—๋Š” ๊ทธ object์— ์ง์ ‘ ์ ์šฉ์ด ๋œ๋‹ค. ์ผ๋‹จ person์€ ์ƒˆ๋กœ์šด object์— ์žฌํ• ๋‹นํ•˜๋ฉด ์›๋ž˜ object์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค.

์ด๋Ÿฌํ•œ ์žฌํ• ๋‹น์€ personObj1์ด ์™ธ๋ถ€ scope์—์„œ ๊ฐ€๋ฆฌํ‚ค๋Š” object๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค. person์ด ์žฌํ• ๋‹น ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ƒˆ๋กœ์šด ์ฐธ์กฐ๊ฐ€ ์žˆ์ง€๋งŒ ์ด ์žฌํ• ๋‹น์€ personObj1์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค.

์œ„์˜ ๋ธ”๋ก๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

var personObj1 = {
    name: 'Alex',
    age: 30
};
var person = personObj1;
person.age = 25;
person = {
  name: 'john',
  age: 50
};
var personObj2 = person;
console.log(personObj1); // -> { name: 'Alex', age: 25 }
console.log(personObj2); // -> { name: 'John', age: '50' }

์œ ์ผํ•œ ์ฐจ์ด์ ์€ ์šฐ๋ฆฌ๊ฐ€ ๊ทธ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, ๊ทธ ํ•จ์ˆ˜๊ฐ€ ์ผ๋‹จ ๋๋‚˜๋ฉด person์€ ๋” ์ด์ƒ ๊ทธ scope์— ์žˆ์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

๋ฐ”๋กœ ๊ทธ๊ฒ๋‹ˆ๋‹ค. ๊ฐ€์„œ ๋ช‡๋ช‡์˜ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ผ.

โ€”โ€Šโ€”โ€Šโ€”โ€Šโ€”โ€Š

๋งŒ์•ฝ ์ด๊ฒƒ์ด ์œ ์šฉํ•˜๋‹ค๋ฉด, ๊ธ€์“ด์ด์˜ ์ž‘ํ’ˆ๋“ค์„ ํ™•์ธํ•ด...

๋ฒˆ์—ญ ์›๋ณธ URL : https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0

์ฐธ์กฐ์™€ ๊ด€๋ จํ•˜์—ฌ ์ •๋ฆฌ ํ–ˆ์—ˆ๋˜ ์—๋ฒ„๋…ธํŠธ ๋งํฌ

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