Bibi's DevLog ๐ค๐
[์ธํ๋ฐ]Javascript์ ๋ฌธ - ์ฐธ์กฐ ๋ณ์์ Call by Reference (์ฐธ์กฐ๋ณ์/์ผ๋ฐ๋ณ์, call by Value/call by Reference) ๋ณธ๋ฌธ
[์ธํ๋ฐ]Javascript์ ๋ฌธ - ์ฐธ์กฐ ๋ณ์์ Call by Reference (์ฐธ์กฐ๋ณ์/์ผ๋ฐ๋ณ์, call by Value/call by Reference)
๋น๋น bibi 2020. 10. 21. 22:19* ์ด ๊ธ์ ์ธํ๋ฐ์์ ์ ๊ณตํ๋ ํธ๋ ์ค๋์ ์ ๋ฃ ๊ฐ์ '์ฝ๊ณ ์์ฐ์ค๋ฝ๊ฒ ๋ฐฐ์๋ณด๋ Javascript ์ ๋ฌธ - ์ฝ๋์ค์ฟผ๋ ๋ง์คํฐ์ฆ ์ฝ์ค ๋ ๋ฒจ1'๋ฅผ ๋ฃ๊ณ ๊ณต๋ถํ๋ฉฐ ์ ๋ฆฌํ ๊ธ์ ๋๋ค. ๊ฐ์ ๋ด์ฉ์ ๋ํด, ์ ๊ฐ ํ๊ธฐํ๊ณ ๊ตฌ๊ธ๋งํ ๋ด์ฉ์ด ์ ๋ฆฌ๋์ด ์์ต๋๋ค. ์ด๋ณด์ธ ์ ๊ฐ ์ดํดํ ๋๋ก ์ ๋ฆฌํ๊ธฐ ๋๋ฌธ์, ๋ถ์ ํํ ๋ด์ฉ์ด ์์ ์ ์์์ ๊ฐ์ํด ์ฃผ์๊ธธ ๋ฐ๋๋๋ค. ๊ฐ์๋ฅผ ๋ฃ๊ณ ๋ด์ฉ์ ์ ๋ฆฌํ ๊ธ์ด๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๊ฐ ๋์ง ์๋๋ค๋ ์ธํ๋ฐ ์ธก ๋ต๋ณ์ ๋ฐ์ ์ ์ด ์์ผ๋(https://bibi6666667.tistory.com/37), ์ ์๊ถ์ ๋ฌธ์ ๊ฐ ๋๋ค๋ฉด ๋ณดํธ ๋ชจ๋(๋น๊ณต๊ฐ)๋ก ์ ํํ๊ฒ ์ต๋๋ค.
๊ฐ์ ์ํ ์ ๋ฌ ์ดํดํ๊ธฐ
์ด๋ฒ ์๊ฐ์๋ ๊ฐ์ ์ํ ์ ๋ฌ(call by Value)๊ณผ ์ฐธ์กฐ์ ์ํ ์ ๋ฌ(call by Reference) ์ ๋น๊ตํด ๋ณผ ๊ฒ์ด๋ค.
๋ณ์์๋ ๋ ์ข ๋ฅ๊ฐ ์๋ค : ์ฐธ์กฐ ๋ณ์์ ์ผ๋ฐ ๋ณ์.
์ฐธ์กฐ ๋ณ์์ ์ผ๋ฐ ๋ณ์ (์ฐธ์กฐ ํ์ ๊ณผ ์์ ํ์ )
"๊ฐ์ฒด"๋ฅผ ๋ณ์์ ํ ๋นํ๋ฉด ์ฐธ์กฐ ๋ณ์๊ฐ ๋๊ณ ,
"๊ธฐ๋ณธ ํ์ "์ ๋ณ์์ ํ ๋นํ๋ฉด ์ผ๋ฐ ๋ณ์๊ฐ ๋ฉ๋๋ค.
- ์ฐธ์กฐ ๋ณ์(์ฐธ์กฐ ํ์
, reference type) : ๋ฐฐ์ด ๋ฑ์ "๊ฐ์ฒด"๊ฐ ํ ๋น๋ ๋ณ์.
(์ฐธ์กฐ ๋ณ์์๋ ๊ฐ์ฒดobject, ๋ฐฐ์ดarray, ํจ์function ๊ฐ ํด๋น๋๋ค)
- ์ผ๋ฐ ๋ณ์(์์ ํ์
, primitive type) : ์ฐธ์กฐ ๋ณ์ ์ธ์ ๋๋จธ์ง ๋ณ์. <- ๊ธฐ๋ณธ ํ์
(์๋ฃํ)์ด ํ ๋น๋ ๋ณ์.
(์ผ๋ฐ ๋ณ์์๋ ์ซ์number, ๋ฌธ์์ดstring, ์ฐธ/๊ฑฐ์งboolean, null, undefined ๊ฐ ํฌํจ๋๋ค)
โป ์ฐธ๊ณ : ๋ค๋ฅธ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ "ํด๋์คclass"๋ผ๋ ๊ฐ๋ ์ด ์๋ฐ์คํฌ๋ฆฝํธ์ "์ฐธ์กฐํ์ /์์ํ์ " ์ ํด๋น๋๋ค.
(๊ทธ๋ฅ ์ธ์ฐ๊ธฐ)
/////// ์ผ๋ฐ ๋ณ์ : ๊ธฐ๋ณธ ํ์
(์๋ฃํ)์ด ํ ๋น๋ ๋ณ์.
var a = 10;
var b = "hello"
// ๋ณ์ a์ number(์ซ์)๋ฅผ ํ ๋นํ์ผ๋ฏ๋ก a๋ ์ผ๋ฐ๋ณ์์ด๋ค.
// ๋ณ์ b์ string(๋ฌธ์์ด)์ ํ ๋นํ์ผ๋ฏ๋ก b๋ ์ผ๋ฐ๋ณ์์ด๋ค.
var c = 5 > 3;
c; //true
// ๋ณ์ c์ true(์ฐธ/๊ฑฐ์ง)์ ํ ๋นํ์ผ๋ฏ๋ก c๋ ์ผ๋ฐ๋ณ์์ด๋ค.
/////// ์ฐธ์กฐ ๋ณ์ : ๊ฐ์ฒด๊ฐ ํ ๋น๋ ๋ณ์.
var d = [1, 2, 3, 4, 5];
// ๋ณ์ d์ ๋ฐฐ์ด์ ํ ๋นํ์ผ๋ฏ๋ก d๋ ์ฐธ์กฐ๋ณ์์ด๋ค.
// (๋ฐฐ์ด๋ ๊ฐ์ฒด์ด๋ค!)
var e = {};
e.name = "honux";
e;
// {name: "honux"}. ๋ณ์ e์ ๊ฐ์ฒด๋ฅผ ํ ๋นํ์ผ๋ฏ๋ก e๋ ์ฐธ์กฐ๋ณ์์ด๋ค.
(์ผ๋ฐ ๋ณ์์ ํน์ง) ์ผ๋ฐ ๋ณ์์์ ๊ฐ ๋ณต์ฌํ๊ธฐ ๋ฐ ๋ฐ๊พธ๊ธฐ
์ผ๋ฐ ๋ณ์๋ "๊ฐ"์ ๋ณต์ฌํด ๊ทธ๋๋ก ์ ์ฅํ๊ณ , ๋ค๋ฅธ ๋ณ์์ ์ธ์ ๋ ๋
๋ฆฝ์ ์ผ๋ก ์กด์ฌํฉ๋๋ค.
(๋ค๋ฅธ ๋ณ์๊ฐ ๋ฐ๋๋๋ผ๋ ์ ๋ณ์๋ ๋ณํ์ง ์๋๋ค)
var a = 10;
var a2 = a; // ๋ณ์ a์ ๊ฐ์ ์ฝ์ด์, a2์ ๋์
ํ๋ค. ๋ฐ๋ผ์ ์ผ๋ฐ๋ณ์ a2์๋ ๊ฐ์ด ๋ค์ด๊ฐ๋ค.
a; // 10
a2; // 10
a2 === a // true
// ๋ณ์ a์ a2๋ ๋ ๋ค 10์ด๋ฏ๋ก ๊ฐ๋ค. ๋ฐ๋ผ์ true๊ฐ ๋์จ๋ค.
// a๋ฅผ 15๋ก ๋ฐ๊ฟ ๋ณธ๋ค.
a = 15
a; // 15
a2; // 10
a2 === a // false
// ๋ณ์ a๋ 15, ๋ณ์ a2๋ 10์ด๋ฏ๋ก ๊ฐ์ด ๋ค๋ฅด๋ค. ๋ฐ๋ผ์ false๊ฐ ๋์จ๋ค (๋น์ฐ)
// ๋ฌธ์์ดstring๋ ๋ง์ฐฌ๊ฐ์ง์ด๋ค.
var s1 = "hello";
var s2 = s1;
s1; // "hello"
s2; // "hello"
s1 === s2 // true
// ๋ณ์ s1๊ณผ s2๋ ๋ ๋ค "hello"์ด๋ฏ๋ก ๊ฐ๋ค. ๋ฐ๋ผ์ true๊ฐ ๋์จ๋ค.
s1 = "hell";
s1 === s2 // false
// ๋ณ์ s1์ "hell", ๋ณ์ s2๋ "hello"์ด๋ฏ๋ก ๊ฐ์ง ์๋ค. ๋ฐ๋ผ์ false๊ฐ ๋์จ๋ค.
์ ์ฝ๋์์ a์ a2, s1๊ณผ s2๋ ์ฒ์์ ๊ฐ์ ๊ฐ์ง๋ง ์ฌ์ค์ ๋ค๋ฅธ ๋ณ์์ ๋๋ค.
์ฐธ์กฐ ๋ณ์์ ๋์ ๋ฐฉ์ ์ดํดํ๊ธฐ
์ฐธ์กฐ ๋ณ์์๋ ์ผ๋ฐ ๋ณ์์ฒ๋ผ ๊ฐ์ด ๋ค์ด์์ง ์๊ณ , "์ฐธ์กฐ"๋ง ๋ค์ด์๋ค.
์ฐธ์กฐ ๋ณ์๋ผ๋ ๊ฒ์ ๊ฐ์ฒด์ ๋ํ ๋ณ๋ช
๊ฐ์ ๊ฒ์
๋๋ค.
์ฐ๋ฆฌ๊ฐ ๊ฐ์ฒด๋ฅผ ๋ง๋ค๋ฉด ๊ฐ์ฒด๊ฐ ์๊ธฐ๊ณ ๋ณ์์๋ ๊ทธ ๊ฐ์ฒด์ ์ฐธ์กฐ๋ฅผ ํ ๋นํ๋ ๊ฑด๋ฐ..... ๋ฌด์จ ๋ง์ธ์ง ์ ๋ชจ๋ฅด๊ฒ ์ฃ ?
๊ฐ์ ์ฌ๋์ ์ด๋ฆ์ผ๋ก๋ ๋ถ๋ฅด๊ณ , ๋ณ๋ช ์ผ๋ก๋ ๋ถ๋ฅด๊ณ , ํ์ค๋น ์ธ๋๋๋์ผ์ด๊ณผ ๊ฐ์ ๋ค์ํ ํธ์นญ์ผ๋ก ๋ถ๋ฅด๋ ๊ฒ๊ณผ ์กฐ๊ธ ๋น์ทํฉ๋๋ค.
(๋ช ์นญ์ ๊ฐ๊ฐ ๋ค๋ฅด์ง๋ง, ๊ฐ๊ฐ์ ๋ช ์นญ์ด ๊ฐ๋ฆฌํค๊ณ ์๋ ๊ฒ์ ๊ฐ๋ค)
์๋ฅผ ๋ค์ด ์ด๋ค ๊ณ ์์ดA๋ฅผ "์ผ์น์ด"๋ผ๊ณ ๋ ๋ถ๋ฅด๊ณ "๋๋น"๋ผ๊ณ ๋ ๋ถ๋ฅด๊ณ "์ ์ฉ์ด"๋ผ๊ณ ๋ ๋ถ๋ฅด์ง๋ง,
"์ผ์น์ด","๋๋น","์ ์ฉ์ด"๊ฐ ๊ฐ๋ฆฌํค๋ ๋์์ ๊ณ ์์ดA๋ก ๋ชจ๋ ๊ฐ๋ค.
๋ง์ฝ ๊ณ ์์ดA์ ๋ชธ๋ฌด๊ฒ๊ฐ 1kg๊ฐ ์ฐ๋ฉด, "์ผ์น์ด","๋๋น","์ ์ฉ์ด"๋ 1kg๊ฐ ์ฐ ๊ฒ์ด๋ค.
โ ์ฐธ์กฐ ๊ฐ reference value : '๊ฐ์ฒด'์ ๊ฐ์ ๋ง์ด๋ค.
์๋ ์ฝ๋๋ฅผ ๋จผ์ ์คํํด ๋ณด์ธ์.
var arr1 = [1, 2, 3, 4, 5];
var arr2 = arr1;
arr2; // [1, 2, 3, 4, 5]
arr1.push(6);
arr1; // [1, 2, 3, 4, 5, 6]
arr2; // [1, 2, 3, 4, 5, 6]
arr1.push(10);
arr1; // [1, 2, 3, 4, 5, 6, 10]
arr2; // [1, 2, 3, 4, 5, 6, 10]
arr1 === arr2 // true
์ฐธ์กฐ ๋ณ์์ ํน์ง : ์ ๋ณ์๊ฐ ๋ฐ๋๋ฉด, ์ฐธ์กฐ ๋ณ์๋ ๋๊ฐ์ด ๋ฐ๋๋ค.
์ฐธ์กฐ ๋ณ์๋ ์ ๋ณ์์ ์์ ํ ๋๊ฐ์ ๊ฐ์ ๊ฐ์ง๊ธฐ ๋๋ฌธ์, arr1 === arr2๋ ์ธ์ ๋ true์ด๋ค.
โ ์?
arr1๋, arr2๋ [1, 2, 3, 4, 5, 6, 10]์ด๋ผ๋ ๊ฐ์ ๋์(๋ฐฐ์ด=๊ฐ์ฒด)์ ์ฐธ์กฐํ๊ณ ์๊ธฐ ๋๋ฌธ์ ๋์ ๊ฐ์ ํญ์ ๊ฐ๋ค.
์ผ๋ฐ ๋ณ์๊ฐ ์๋, ๊ฐ์ฒด๋ฅผ ํ ๋นํ "์ฐธ์กฐ๋ณ์"์ด๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฅํ๋ค.
// ๊ฐ์ฒด์ ๊ฒฝ์ฐ
var p1 = {};
var p2 = p1;
p1 === p2; // true
p1.name = "honux";
p1 === p2 // true.
p1; // {name: "honux"}
p2; // {name: "honux"}
var m1 = {name: "honux", age: 25};
var m2 = m1;
m1 === m2; // true
m2.name = "crong";
m2; // {name: "crong", age: 25};
m1; // {name: "crong", age: 25};
m1 === m2; // true
- ๊ฐ์ ๋์์ ์ฐธ์กฐํ๋ ์ฐธ์กฐ๋ณ์๋ผ๋ฆฌ๋ ์ธ์ ๋ ๊ฐ์ ๊ฐ์ ๊ฐ์ง๋ค.
- ํ ์ฐธ์กฐ๋ณ์์ ๊ฐ์ ๋ฐ๊พธ์ด๋ "์ฐธ์กฐ ๋์"์ ๊ฐ์ด ๋ฐ๋๋ฏ๋ก, ๋ ์ฐธ์กฐ๋ณ์๋ ๊ฐ๋ค.
์ผ๋ฐ ๋ณ์์๋ ์ ํ ๋ค๋ฅธ ๊ฒฐ๊ณผ๊ฐ ๋์์ฃ ? ์ ๊ทธ๋ฐ์ง๋ ๋์ค์ ์ ์ ๋ก ์๊ฒ ๋ฉ๋๋ค. ์ผ๋จ ์ด๊ฒ ์ฐธ์กฐ ๋ณ์๊ตฌ๋ํ๊ณ ๊ธฐ์ตํด ๋ก์๋ค.
ํจ์ ํธ์ถ์์ ๋ณ์
ํจ์์์ ๋ ์ฝ๋์ ๋์ ์ฐจ์ด๋ฅผ ๋ด ์๋ค.
- ์ผ๋ฐ ๋ณ์ primitive type : ๊ฐ์ ์ํ ์ ๋ฌ. call by Value
- ์ฐธ์กฐ ๋ณ์ reference type : ์ฐธ์กฐ์ ์ํ ์ ๋ฌ. call by Reference
์๋ ์์ ๋ฅผ ํตํด ์ดํดํด ๋ณด์.
๊ฐ ์ ๋ฌ call by Value (์ผ๋ฐ ๋ณ์)
var foo = function(v) {
v = v * 2;
console.log("foo: " + v);
}
var n = 10;
foo(n); // foo: 20 ์ด ์ถ๋ ฅ๋๋ค.
n; // 10.
ํจ์ foo(v)์ n์ด๋ผ๋ ๋งค๊ฐ๋ณ์์ "๊ฐ"์ธ 10์ด ๋ค์ด๊ฐ, 2๊ฐ ๊ณฑํด์ง๊ณ ์ฝ์ ์ฐฝ์ ์ฐํ๋ค.
n์ด ๋ค์ด๊ฐ๋ ๊ฒ ์๋, n์ "๊ฐ"์ธ 10์ด ๋ค์ด๊ฐ๊ธฐ ๋๋ฌธ์ n์ ๊ทธ๋๋ก์ด๋ค.
์ฐธ์กฐ ์ ๋ฌ call by Reference (์ฐธ์กฐ ๋ณ์)
// ๋ฐฐ์ด์ ๊ฒฝ์ฐ
var arr = [1, 2, 3, 4, 5];
var append = function(arr, v) [
arr.push(v);
};
append(arr, 10);
arr; // [1, 2, 3, 4, 5, 10]
var a = []; // ๋น์ด ์๋ ๋ฐฐ์ด.
append(a2, 1);
a2; // [1]
append(a2, 2);
a2; // [1, 2]
append(a2, 100);
a2; // [1, 2, 100]
- ๋ฐฐ์ด๋ ๊ฐ์ฒด์ด๊ธฐ ๋๋ฌธ์, ์ฐธ์กฐ์ ์ํด ๊ฐ์ด ์ ๋ฌ(call by Reference)๋์ด
ํจ์ ๋ด์์ ๋ฐ๊พผ ๊ฐ์ด ํจ์ ๋ฐ๊นฅ์์๋ ๋ฐ๋๋ค.
(ํจ์ append ๋ด์์ .push();๋ฅผ ํ๋ฉด ํจ์ ๋ฐ๊นฅ์ arr๊ฐ๋ ๋ณํ๋ค.)
// ๊ฐ์ฒด์ ๊ฒฝ์ฐ
var p1 = {name : "honux"}
p1.weight = 67;
p1; // {name : "honux", weight : 67}
var diet = function(people) {
people.weight -= 1;
console.log("%s %d", people.name, people.weight);
};
diet(p1); // honux 66
// ์ฒด์ค์ด 1 ๊ฐ์ํ๋ค.
p1; // {name: "honux", weight: 61}
- ๊ฐ์ฒด p1 ์ญ์ ์ฐธ์กฐ์ ์ํด ๊ฐ์ด ์ ๋ฌ๋๊ธฐ ๋๋ฌธ์,
ํจ์ diet();๋ด์์ people.weight๋ฅผ -1์ฉ ๋นผ๋ฉด ํจ์ ๋ฐ๊นฅ์ p1.weight๋ -1์ฉ ๋น ์ง๋ค
โ ์ผ๋ฐ ๋ณ์('๊ฐ ์ฐธ์กฐ' ์์ )์ ๋ค๋ฅด๊ฒ..
ํจ์์ ๋งค๊ฐ๋ณ์๋ก ์ฐธ์กฐ๋ณ์๋ฅผ ๋ฃ๊ณ , ํจ์ ์์์ ๊ฐ์ ๋ฐ๊พธ๋ฉด ํจ์ ๋ฐ๊นฅ์ ๊ฐ์ฒด๋ ๊ฐ์ด ๋ฐ๋๋ค.
์? p1๊ณผ people์ด ๊ฐ๊ธฐ ๋๋ฌธ!
-> ์ด๋ฌํ ๊ฐ ์ ๋ฌ๋ฐฉ์์ "์ฐธ์กฐ์ ์ํ ์ ๋ฌ" call by Reference ์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค.
์์ฝ
- ๊ฐ ์ ๋ฌ ๋ณ์(=์ผ๋ฐ๋ณ์, primitive type)๋ ํจ์ ๋ด๋ถ์์ ๊ฐ์ ๋ฐ๊ฟ๋ ์ธ๋ถ์์๋ ๊ทธ๋๋ก์
๋๋ค.
์? ์ผ๋ฐ๋ณ์๋ ๊ฐ๋ง ์ ๋ฌํด ์ฃผ๊ธฐ ๋๋ฌธ. - ์ฐธ์กฐ ์ ๋ฌ ๋ณ์(=์ฐธ์กฐ๋ณ์, reference type)๋ ํจ์ ๋ด๋ถ์์ ๊ฐ์ ๋ฐ๊พธ๋ฉด ์ธ๋ถ์ ๊ฐ์ฒด๋ ๊ฐ์ด ๋ฐ๋๋๋ค.
์ด๋ฒ ์๊ฐ์ ์์ฃผ ์ค์ํ ๋ด์ฉ์ด๊ธฐ ๋๋ฌธ์, ๊ผญ ์์งํ๊ณ ๋ค์ ๋จ๊ณ๋ก ๋์ด๊ฐ๋ ๊ฒ์ ์ถ์ฒํ๋ค.