[Javascript] ๐Ÿ“š Call by Value & Call by Reference (feat. Call by Sharing)

Yoochanยท2022๋…„ 12์›” 21์ผ
0
post-thumbnail

ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๊ณต๋ถ€ํ•œ๋‹ค๋ฉด call by value, call by reference๋ฅผ ๋“ค์–ด๋ดค์„ ๊ฒƒ์ด๋ฉฐ,๊ตฌ๊ธ€์— ๊ฒ€์ƒ‰ํ•ด๋ณด๋ฉด ์ด ๋‘ ์šฉ์–ด๋ฅผ ์„ค๋ช…ํ•ด์ฃผ๋Š” ๋งŽ์€ ์ž๋ฃŒ๋“ค์ด ์กด์žฌํ•œ๋‹ค. ๊ณต๋ถ€๋ฅผ ํ•˜๋‹ค๊ฐ€ ์ด ๋‘ ๊ฐœ๋…์— ๋Œ€ํ•ด ๋” ์ž์„ธํ•˜๊ฒŒ ์•Œ์•„๋ณด๊ณ  ์‹ถ์–ด์„œ ํŒŒํ›ผ์น˜๋‹ค๋ณด๋‹ˆ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์‚ฌ์‹ค call by value๋งŒ ์กด์žฌํ•œ๋‹ค๋Š” ํฅ๋ฏธ๋กœ์šด ๊ธ€๋“ค์„ ์ ‘ํ–ˆ๋‹ค. ์ฒ˜์Œ์—” ๊ธฐ์กด์— ์•Œ๊ณ  ์žˆ๋˜ ๊ฐœ๋…๊ณผ ๋’ค์„ž์ด๋Š” ๋Š๋‚Œ์ด๋ผ ํ˜ผ์žกํ•˜๊ฒŒ ๋Š๊ปด์กŒ์ง€๋งŒ, ์ฐจ๊ทผ์ฐจ๊ทผ ๋œฏ์–ด๋ณด๋ฉฐ ๊ณต๋ถ€ํ•˜๊ณ  ํ•ด๋‹น ๋‚ด์šฉ์„ ์ •๋ฆฌํ–ˆ๋‹ค.

call by ~

call by ๋ญ์‹œ๊ธฐ ํ•˜๋Š” ๊ฒƒ์€ย ํ‰๊ฐ€ ์ „๋žต(Evaluation Strategy) ์ค‘์— ํ•˜๋‚˜์ด๋‹ค. ์•„๋ž˜๋Š” ํ‰๊ฐ€ ์ „๋žต์— ๋Œ€ํ•œ ์œ„ํ‚คํ”ผ๋””์•„์˜ ์ •์˜์ด๋‹ค.

ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์—์„œ ํ•จ์ˆ˜ ํ˜ธ์ถœ์˜ ์•„๊ทœ๋จผํŠธ(argument)์˜ ์ˆœ์„œ๋ฅผ ์–ธ์ œ ๊ฒฐ์ •ํ•˜๊ณ  ํ•จ์ˆ˜์— ์–ด๋–ค ์ข…๋ฅ˜์˜ ๊ฐ’์„ ํ†ต๊ณผ์‹œํ‚ฌ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ

ํ•จ์ˆ˜ ์ธ์ž์— ๋ฌด์—‡์„ ๋˜์ง€๋Š๋ƒ์— ๋”ฐ๋ผ, ์–ด๋–ป๊ฒŒ ์‹คํ–‰๋ ์ง€์— ๋Œ€ํ•œ ๋ฐฉ๋ฒ•์„ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
๋Œ€ํ‘œ์ ์ธ ํ˜ธ์ถœ ๋ฐฉ๋ฒ•๋“ค๋กœ๋Š” call by value์™€ call by reference๊ฐ€ ์žˆ๋‹ค.

parameter vs arguments

ํ˜ธ์ถœ ๋ฐฉ๋ฒ•๋“ค์„ ์‚ดํŽด๋ณด๊ธฐ ์ „์— parameter(๋งค๊ฐœ๋ณ€์ˆ˜)์™€ arguments(์ธ์ž)์— ๋Œ€ํ•ด ์งš๊ณ  ๋„˜์–ด๊ฐ€์•ผํ•œ๋‹ค.

  • parameter : formal parameter(ํ˜•์‹ ๋งค๊ฐœ๋ณ€์ˆ˜)
  • arguments : actual parameter(์‹ค์ธ์ž)

parameter๋Š”ย ํ•จ์ˆ˜ ์„ ์–ธ๋ถ€์— ์ •์˜๋˜๊ณ , arguments๋Š”ย ํ•จ์ˆ˜ ํ˜ธ์ถœ๋ถ€์—์„œ ์‚ฌ์šฉ๋œ๋‹ค.

call by value

  • ํ•จ์ˆ˜ ํ˜ธ์ถœ์‹œ ์ „๋‹ฌ๋ฐ›์€ ์ธ์ž(argument)๊ฐ€ย ์›์‹œ ํƒ€์ž…์ด๋ฉด? โ†’ ์›๋ณธ ๊ฐ’์„ย ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌํ•˜์—ฌย ๋งค๊ฐœ๋ณ€์ˆ˜(parameter)๋กœ ์ „๋‹ฌํ•œ๋‹ค
    • ์›์‹œํƒ€์ž… - string, number, bigint, boolean, undefined, ES6 ๋ถ€ํ„ฐ ์ถ”๊ฐ€๋œ symbol
  • ์›๋ณธ ๊ฐ’์ด ํ•จ์ˆ˜์˜ย ์˜ํ–ฅ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค

์˜ˆ์‹œ๋กœ ์‚ดํŽด๋ณด์ž

let a = 1;
let func = function(b) { // callee
  b = b + 1;
}
func(a); // caller
console.log(a); // 1

๋ณ€์ˆ˜ a๋Š” ์›์‹œ ํƒ€์ž…์ธ ์ˆซ์ž 1์„ ์ €์žฅํ•˜๊ณ  ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ call by value์˜ ํ˜•ํƒœ๋กœ ์ž‘๋™ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ caller๊ฐ€ 1์„ arguments๋กœ ๋„˜๊ฒจ์ค˜๋„ ๊ทธ ๊ฐ’์€ ๋ณต์‚ฌ๋˜์–ด ๋„˜์–ด์˜ค๊ธฐ ๋•Œ๋ฌธ์— callee ๋‚ด๋ถ€์—์„œ ์–ด๋– ํ•œ ์ž‘์—…์„ ์ง„ํ–‰ํ•ด๋„ ์ „ํ˜€ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์•„์„œ ๊ฒฐ๊ณผ์ ์œผ๋กœ a ๊ฐ’์€ ์›๋ž˜ ๊ฐ’์ธ 1์ด ์ฐํžˆ๊ฒŒ ๋œ๋‹ค.

call by reference

  • ํ•จ์ˆ˜ ํ˜ธ์ถœ์‹œ ์ „๋‹ฌ๋ฐ›์€ ์ธ์ž(argument)๊ฐ€ย ์ฐธ์กฐ ํƒ€์ž…์ด๋ฉด? โ†’ ์ธ์ž์˜ย ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๊ฐ’(์ฐธ์กฐ)์„ ๋งค๊ฐœ๋ณ€์ˆ˜(parameter)๋กœ ์ „๋‹ฌํ•œ๋‹ค
    • ์›์‹œํƒ€์ž…์„ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€๋Š” ์ฐธ์กฐ ํƒ€์ž…์ด๋‹ค
  • ์›๋ณธ ๊ฐ’์ด ํ•จ์ˆ˜์˜ย ์˜ํ–ฅ์„ ๋ฐ›๋Š”๋‹ค

์˜ˆ์‹œ๋กœ ์‚ดํŽด๋ณด์ž

let a = {};
let func = function(b) { // callee
  b.a = 1;
}
func(a); // caller
console.log(a.a); // 1

call by sharing

๊ฐ‘์ž๊ธฐ call by sharing ์ด๋ผ๋Š” ๊ฐœ๋…์ด ํŠ€์–ด๋‚˜์™”๋‹ค. ์šฐ์„  ์•„๋ž˜ ์˜ˆ์‹œ๋ถ€ํ„ฐ ์‚ดํŽด๋ณด์ž.

function update(num , ref1 , ref2){
  num += num
  ref1.name = 'updated!'
  ref2 = { name : 'changed' }
}

let number = 1;
let object1 = { name : 'updated!'};
let object2 = { name : 'not updated'};

change(number,object1,object2)

console.log(number) // 1
console.log(object1) // {name: 'updated!'}
console.log(object2) // {name: 'not updated'}

number๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜๊ณ  (call by value)

object1์€ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค (call by reference).

์œ„์˜ ๋‘ ๊ฒฐ๊ณผ๋Š” ์ •์ƒ์ ์ด๋‹ค. ํ•˜์ง€๋งŒ object2๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜๋‹ค.

์™œ ์ด๋Ÿฐ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ๊นŒ? ์‚ฌ์‹ค ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ๋ฌด์กฐ๊ฑด call by value๋กœ ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด๋ฅผ call by sharing์ด๋ž€ ๊ฐœ๋…์œผ๋กœ ์„ค๋ช…ํ•œ๋‹ค.

๋„์‹ํ™”๋ฅผ ํ•ด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

object2๋Š” ๊ฐ์ฒด์ธ ์ฐธ์กฐ ํƒ€์ž…์ด๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ์ธ 0x100๊ฐ€ ๋‹ด๊ฒจ์žˆ๋‹ค(๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ ์ž„์‹œ๋กœ ์„ค์ •).
object2์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ’์„ ๋ณต์‚ฌํ•œ ref2๊ฐ€ ์ƒˆ๋กœ ์ƒ์„ฑ๋œ๋‹ค. ์ด๋•Œ๊นŒ์ง€๋Š” ์ฐธ์กฐ๋œ ๊ฐ’์ด object2์™€ ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋‹ค.

function update(num , ref1 , ref2)

๊ทธ ์ดํ›„์—,
= ์—ฐ์‚ฐ์ž๋กœ ์ฐธ์กฐ๊ฐ’์„ ์žฌํ• ๋‹นํ•˜๊ธฐ ๋•Œ๋ฌธ์— ref2๋Š” ์ƒˆ๋กœ์šด ๊ฐ์ฒด์˜ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๊ฐ’์ธ 0x200์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

let object2 = { name : 'not updated'};

๊ทธ๋ž˜์„œ ๊ฒฐ๋ก ์€?

  • ๊ฒฐ๊ตญ JavaScript์—๋Š” call by reference๊ฐ€ ์กด์žฌ ํ•˜์ง€ ์•Š๋Š”๋‹ค(๋ฉ”๋ชจ๋ฆฌ ์ง์ ‘ ํ•ธ๋“ค๋ง ๋ถˆ๊ฐ€๋Šฅ).
  • ์ฐธ์กฐ ํƒ€์ž… ์ธ์ž๋„ ๋ณต์‚ฌํ•ด์„œ ์ „๋‹ฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— call by value๋งŒ ์กด์žฌํ•œ๋‹ค๊ณ ๋„ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ด๋Ÿฌํ•œ ํ˜ผ๋™์œผ๋กœ ์ธํ•ด call by sharing์ด๋ž€ ์šฉ์–ด๋กœ ์„ค๋ช…ํ•˜์ง€๋งŒ, ์ •์‹ ์šฉ์–ด๋Š” ์•„๋‹ˆ๋‹ค.

ps)
wiktionary์—์„œ ์ •์˜ํ•œ call by sharing

ํ•จ์ˆ˜์— ์ „๋‹ฌ๋œ ์ธ์ˆ˜๊ฐ€ ํ˜ธ์ถœ์ž์—๊ฒŒ ํ‘œ์‹œ๋˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์ง€๋งŒ(call-by-value์™€ ๋‹ฌ๋ฆฌ) ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋œ ํŠน์ • ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์•ก์„ธ์Šค๊ฐ€ ์ œ๊ณต๋˜์ง€ ์•Š๋Š” ํ‰๊ฐ€ ์ „๋žต(call-by-reference์™€ ๋‹ฌ๋ฆฌ).

์ฐธ๊ณ  ์ž๋ฃŒ
[Java Script] ์›์‹œํƒ€์ž…๊ณผ ์ฐธ์กฐํƒ€์ž… ๐Ÿ‘€
(์ž์•Œ์“ฐ) call by value vs call by reference
์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ - Call by value/ Call by reference/ Call by sharing
call by sharing - Wiktionary

profile
FrontEnd Developer

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