Programming/JavaScript

[λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ Deep Dive] 11μž₯ μ›μ‹œ κ°’κ³Ό 객체의 비ꡐ, 얇은 볡사 κΉŠμ€ 볡사

yuri lee 2023. 5. 21. 17:26
λ°˜μ‘ν˜•

μžλΉ„μŠ€ν¬λ¦½νŠΈκ°€ μ œκ³΅ν•˜λŠ” 7가지 데이터 νƒ€μž… (숫자, λ¬Έμžμ—΄, λΆˆλ¦¬μ–Έ, Null, undfined, μ‹¬λ²Œ, 객체 νƒ€μž…)은 크게 μ›μ‹œ νƒ€μž…κ³Ό κ°μ²΄νƒ€μž…μœΌλ‘œ ꡬ뢄할 수 μžˆμŠ΅λ‹ˆλ‹€. 

 

- μ›μ‹œ νƒ€μž…μ˜ 값은 λ³€κ²½ λΆˆκ°€λŠ₯ν•œ κ°’μž…λ‹ˆλ‹€. 객체 νƒ€μž…μ˜ 값은 λ³€κ²½ κ°€λŠ₯ν•œ κ°’μž…λ‹ˆλ‹€. 

- μ›μ‹œ 값을 λ³€μˆ˜ ν• λ‹Ή μ‹œ λ³€μˆ˜(ν™•λ³΄λœ λ©”λͺ¨λ¦¬ 곡간)μ—λŠ” μ‹€μ œ 값이 μ €μž₯λ©λ‹ˆλ‹€. 객체 λ³€μˆ˜ ν• λ‹Ή μ‹œ λ³€μˆ˜(ν™•λ³΄λœ λ©”λͺ¨λ¦¬ 곡간)μ—λŠ” μ°Έμ‘° 값이 μ €μž₯λ©λ‹ˆλ‹€. 

- μ›μ‹œ κ°’ λ³€μˆ˜λ₯Ό λ‹€λ₯Έ λ³€μˆ˜μ— ν• λ‹Ή μ‹œ 값에 μ˜ν•œ 전달 (pass by value)라고 ν•˜κ³ , 객체λ₯Ό κ°€λ¦¬ν‚€λŠ” λ³€μˆ˜λ₯Ό λ‹€λ₯Έ λ³€μˆ˜μ— ν• λ‹Ήν•˜λ©΄ 참쑰에 μ˜ν•œ 전달 (pass by reference)라고 ν•©λ‹ˆλ‹€. 

 

11.1 μ›μ‹œ κ°’


11.1.1 λ³€κ²½ λΆˆκ°€λŠ₯ν•œ κ°’

const o = {}; // const ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•΄ μ„ μ–Έν•œ λ³€μˆ˜λŠ” μž¬ν• λ‹Ήμ΄ κΈˆμ§€λœλ‹€. μƒμˆ˜λŠ” μž¬ν• λ‹Ήμ΄ κΈˆμ§€λœ λ³€μˆ˜μΌ 뿐이닀. 


// const ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•΄ μ„ μ–Έν•œ λ³€μˆ˜μ— ν• λ‹Ήν•œ μ›μ‹œ 값은 λ³€κ²½ν•  수 μ—†μŒ
// const ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•΄ μ„ μ–Έν•œ λ³€μˆ˜μ— ν• λ‹Ήν•œ κ°μ²΄λŠ” λ³€κ²½ν•  수 있음 
o.a = 1;
console.log(o); // {a: 1}

λΆˆλ³€μ„±μ„ κ°–λŠ” μ›μ‹œ 값을 ν• λ‹Ήν•œ λ³€μˆ˜λŠ” μž¬ν• λ‹Ή 이외에 λ³€μˆ˜ 값을 λ³€κ²½ν•  수 μžˆλŠ” 방법이 μ—†μŠ΅λ‹ˆλ‹€.

 

11.1.2 λ¬Έμžμ—΄κ³Ό λΆˆλ³€μ„±

μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ λ¬Έμžμ—΄μ€ μ›μ‹œνƒ€μž…μ΄λ©°, λ³€κ²½ λΆˆκ°€λŠ₯ν•©λ‹ˆλ‹€. 

λ‹€λ§Œ, λ¬Έμžμ—΄μ€ μœ μ‚¬ λ°°μ—΄ κ°μ²΄μ΄λ©΄μ„œ μ΄ν„°λŸ¬λΈ”μ΄λ―€λ‘œ λ°°μ—΄κ³Ό μœ μ‚¬ν•˜κ²Œ λ¬Έμžμ— μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€. 

var str = "string";

console.log(str[0]); // s
console.log(str.length); // 6
console.log(str.toUpperCase()); // STRING

 

11.1.3 값에 μ˜ν•œ 전달 

var score = 80;

var copy = score;

console.log(score, copy);
console.log(score === copy);

score = 100;

console.log(score, copy);
console.log(score == copy);


// 80 80
// true
// 100 80
// false

score λ³€μˆ˜μ™€ copy λ³€μˆ˜μ˜ κ°’ 80은 λ‹€λ₯Έ λ©”λͺ¨λ¦¬ 곡간에 μ €μž₯된 λ³„κ°œμ˜ κ°’μž…λ‹ˆλ‹€ . 사싀 μ—„κ²©ν•˜κ²Œ λ§ν•˜λ©΄ λ³€μˆ˜μ— 값이 μ „λ‹¬λ˜λŠ” 게 μ•„λ‹ˆλΌ λ©”λͺ¨λ¦¬ μ£Όμ†Œκ°€ μ „λ‹¬λ˜λŠ” κ²ƒμž…λ‹ˆλ‹€. λ‘ λ³€μˆ˜μ˜ 값은 μ„œλ‘œ λ‹€λ₯Έ λ©”λͺ¨λ¦¬ 곡간에 μ €μž₯된 λ³„κ°œμ˜ 값이 λ˜μ–΄ μ–΄λŠ ν•œμͺ½μ—μ„œ μž¬ν• λ‹Ήμ„ 톡해 값을 λ³€κ²½ν•˜λ”λΌλ„ μ„œλ‘œ κ°„μ„­ν•  수 μ—†μŠ΅λ‹ˆλ‹€. 

 

11.2 객체


11.2.1 λ³€κ²½ κ°€λŠ₯ν•œ κ°’

객체(μ°Έμ‘°) νƒ€μž…μ˜ κ°’, 즉 κ°μ²΄λŠ” λ³€κ²½ κ°€λŠ₯ν•œ κ°’μž…λ‹ˆλ‹€.

// 할당이 μ΄λ€„μ§€λŠ” μ‹œμ μ— 객체 λ¦¬ν„°λŸ΄μ΄ ν•΄μ„λ˜κ³ , κ·Έ κ²°κ³Ό 객체가 μƒμ„±λ©λ‹ˆλ‹€ .
var person = {
	name: 'Lee'
}

// person λ³€μˆ˜μ— μ €μž₯λ˜μ–΄ μžˆλŠ” μ°Έμ‘° κ°’μœΌλ‘œ μ‹€μ œ 객체에 μ ‘κ·Όν•©λ‹ˆλ‹€. 
console.log(person) // { name: "Lee"}

μ›μ‹œ 값은 λ³€κ²½ λΆˆκ°€λŠ₯ν•œ κ°’μ΄λ―€λ‘œ μž¬ν• λ‹Ή μ™ΈλŠ” 방법이 μ—†μ§€λ§Œ κ°μ²΄λŠ” λ³€κ²½ κ°€λŠ₯ν•œ κ°’μž…λ‹ˆλ‹€. 

 

얕은 볡사(shallow copy)와 κΉŠμ€ 볡사(deep copy)

객체λ₯Ό ν”„λ‘œνΌν‹° κ°’μœΌλ‘œ κ°–λŠ” 객체의 경우 얇은 λ³΅μ‚¬λŠ” ν•œ λ‹¨κ³„κΉŒμ§€ 볡사, κΉŠμ€ λ³΅μ‚¬λŠ” 객체에 μ€‘μ²©λ˜μ–΄ μžˆλŠ” κ°μ²΄κΉŒμ§€ λͺ¨λ‘ λ³΅μ‚¬ν•˜λŠ” 것을 λ§ν•©λ‹ˆλ‹€. 

 

얇은 볡사와 κΉŠμ€ λ³΅μ‚¬λ‘œ μƒμ„±λœ κ°μ²΄λŠ” 원본과 λ‹€λ₯Έ κ°μ²΄μ΄λ―€λ‘œ μ°Έμ‘° 값이 λ³„κ°œμ˜ κ°μ²΄μž…λ‹ˆλ‹€. 참고둜 μ›μ‹œ 값을 ν• λ‹Ήν•œ λ³€μˆ˜λ₯Ό λ‹€λ₯Έ λ³€μˆ˜μ— ν• λ‹Ήν•˜λŠ” 것을 κΉŠμ€ 볡사, 객체λ₯Ό ν• λ‹Ήν•œ λ³€μˆ˜λ₯Ό λ‹€λ₯Έ λ³€μˆ˜μ— ν• λ‹Ήν•˜λŠ” 것을 얕은 볡사라고 λΆ€λ₯΄λŠ” κ²½μš°λ„ μžˆμŠ΅λ‹ˆλ‹€. 

const v = 1;

// "κΉŠμ€ 볡사" 라고 λΆ€λ₯΄κΈ°λ„ ν•œλ‹€.
const c1 = v;
console.log(c1 === v); // true

const o = { x: 1 };

const c2 = o;
console.log(c2 === o); // true

 

 

11.2.2 참쑰에 μ˜ν•œ 전달

var person = {
  name: 'Lee'
}

// μ°Έμ‘° 값을 볡사 (얕은 볡사)
var copy = person

μ›λ³Έμ˜ μ°Έμ‘° 값이 λ³΅μ‚¬λ˜μ–΄ μ „λ‹¬λ˜μ—ˆμœΌλ―€λ‘œ 참쑰에 μ˜ν•œ 전달이라고 ν•©λ‹ˆλ‹€. 2개의 μ‹λ³„μžκ°€ ν•˜λ‚˜μ˜ 객체λ₯Ό κ³΅μœ ν•˜κ³  있기 λ•Œλ¬Έμ— 원본 λ˜λŠ” 사본 쀑 μ–΄λŠ ν•œμͺ½μ—μ„œ 객체λ₯Ό λ³€κ²½ν•˜λ©΄ 영ν–₯을 μ£Όκ³  λ°›μŠ΅λ‹ˆλ‹€.

 

var person = {
  name: "Lee",
};

// μ°Έμ‘° 값을 볡사 (얕은 볡사)
var copy = person;

// λ™μΌν•œ 객체λ₯Ό μ°Έμ‘°ν•œλ‹€
console.log(copy === person);

// λ³€κ²½
copy.name = "Kim";
person.address = "Seoul";

// copy와 person은 λ™μΌν•œ 객체λ₯Ό 가리킨닀
// λ”°λΌμ„œ μ–΄λŠ ν•œμͺ½μ—μ„œ 객체λ₯Ό λ³€κ²½ν•˜λ©΄ μ„œλ‘œ 영ν–₯을 μ£Όκ³  λ°›μŒ
console.log(person);
console.log(copy);

값에 μ˜ν•œ 전달, 참쑰에 μ˜ν•œ 전달은 κ²°κ΅­ μ‹λ³„μžκ°€ κΈ°μ–΅ν•˜λŠ” λ©”λͺ¨λ¦¬ 곡간에 μ €μž₯λ˜μ–΄ μžˆλŠ” 값을 볡사 μ „λ‹¬ν•œλ‹€λŠ” λ©΄μ—μ„œ λ™μΌν•©λ‹ˆλ‹€. 

 

ν€΄μ¦ˆ

var person = {
  name: "Lee",
};

var person2 = {
  name: "Lee",
};

console.log(person === person2); // false
console.log(person.name === person2.name); // true

person, person2 λ³€μˆ˜κ°€ κ°€λ¦¬ν‚€λŠ” κ°μ²΄λŠ” λ‚΄μš©μ€ κ°™μ§€λ§Œ λ‹€λ₯Έ λ©”λͺ¨λ¦¬μ—μ„œ μ €μž₯된 λ³„κ°œμ˜ κ°μ²΄μž…λ‹ˆλ‹€. λ”°λΌμ„œ false, ν•˜μ§€λ§Œ ν”„λ‘œνΌν‹° 값을 μ°Έμ‘°ν•˜λŠ” name은 κ°’μœΌλ‘œ 평가될 수 μžˆλŠ” ν‘œν˜„μ‹μ΄λ―€λ‘œ true μž…λ‹ˆλ‹€. 

 

 


Reference: λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ Deep Dive
λ°˜μ‘ν˜•