prototype inheritance - Lee-hyuna/33-js-concepts-kr GitHub Wiki

μ›ν˜• 상속

원문: Prototypal inheritance

ν”„λ‘œκ·Έλž˜λ°μ—μ„œ μ’…μ’… 무언가λ₯Ό ν™•μž₯ν•˜κΈ°λ₯Ό μ›ν•œλ‹€.

예λ₯Όλ“€μ–΄, 속성듀과 λ©”μ„œλ“œλ₯Ό 가진 user 객체가 있고 이λ₯Ό μ•½κ°„ λ³€ν˜•ν•˜μ—¬ adminκ³Ό guestλ₯Ό λ§Œλ“œλ €κ³  ν• λ•Œ user에 μžˆλŠ” 것듀을 μž¬μ‚¬μš©ν•˜κ³  싢을 것이닀. 즉, λ©”μ„œλ“œλ₯Ό 볡사/μž¬μž‘μ„±ν•˜μ§€ μ•Šκ³  μƒˆλ‘œμš΄ 객체λ₯Ό λ§Œλ“€κ³  싢을 것이닀.

이λ₯Ό μœ„ν•΄ μ›ν˜• 상속(Prototypal inheritance)μ΄λΌλŠ” νŠΉμ§•μ΄ μ‘΄μž¬ν•œλ‹€.

Prototype

μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 객체(object)λŠ” null μ΄κ±°λ‚˜ λ‹€λ₯Έ 객체λ₯Ό μ°Έμ‘°ν•˜λŠ” μˆ¨κ²¨μ§„ 속성인 [Prototype](/Lee-hyuna/33-js-concepts-kr/wiki/Prototype)을 가지고 μžˆλ‹€. (μŠ€νŽ™ λ¬Έμ„œμ— μ ν˜€μžˆλ“―μ΄). 이 객체λ₯Ό "ν”„λ‘œν† νƒ€μž…"이라 ν•œλ‹€.

/resource/yongkwan/17/01.png

ν”„λ‘œν† νƒ€μž…μ€ μ•½κ°„ λ§ˆλ²•κ°™λ‹€. objectμ—μ„œ 속성 값을 μ ‘κ·Όν•˜λ €κ³  ν• λ•Œ, ν•΄λ‹Ή 값이 μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ©΄ μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” μžλ™μ μœΌλ‘œ κ·Έ 객체의 ν”„λ‘œν† νƒ€μž…(μ›ν˜•)μ—μ„œ κ·Έ 값을 κ°€μ Έμ˜¨λ‹€. λ§Žμ€ μ–Έμ–΄λ“€μ˜ νŠΉμ§•λ“€κ³Ό ν”„λ‘œκ·Έλž˜λ° 기술이 이λ₯Ό ν† λŒ€λ‘œν•œλ‹€.

[Prototype](/Lee-hyuna/33-js-concepts-kr/wiki/Prototype) 속성은 λ‚΄λΆ€μ μœΌλ‘œ 숨겨져 μžˆλŠ”λ°, 이λ₯Ό μ„€μ •ν•˜λŠ” 방법은 μ—¬λŸ¬κ°€μ§€κ°€ μ‘΄μž¬ν•œλ‹€.

κ·Έ 쀑 ν•˜λ‚˜κ°€ μ•„λž˜μ™€ 같이 __proto__λ₯Ό μ‚¬μš©ν•˜λŠ” 것이닀.

let animal = {
  eats: true
};
let rabbit = {
  jumps: true
};

rabbit.__proto__ = animal;

__proto__ λŠ” [Prototype](/Lee-hyuna/33-js-concepts-kr/wiki/Prototype)을 μœ„ν•œ historical getter/setter이닀.

__proto__와 [Prototype](/Lee-hyuna/33-js-concepts-kr/wiki/Prototype)κ³Ό _같지 μ•Šλ‹€_λŠ” 것을 기얡해라. __proto__λŠ” [Prototype](/Lee-hyuna/33-js-concepts-kr/wiki/Prototype)의 getter/setter이닀.

__proto__λŠ” 역사적 이유둜 μ‘΄μž¬ν•˜λŠ”λ°, ν˜„λŒ€ μ–Έμ–΄μ—μ„œλŠ” Object.getPrototypeOf/Object.setPrototypeOf 같은 ν•¨μˆ˜ ν˜•νƒœλ‘œ λŒ€μ²΄λ˜μ—ˆλ‹€. μ’€ 더 λ‚˜μ€‘μ— λŒ€μ²΄λœ μ΄μœ μ™€ ν•΄λ‹Ή ν•¨μˆ˜λ₯Ό μ‚΄νŽ΄ λ³Ό 것이닀.

μŠ€νŽ™μ— λ”°λ₯΄λ©΄ __proto__λŠ” λΈŒλΌμš°μ €μ— μ˜ν•΄μ„œλ§Œ μ§€μ›λ˜μ–΄μ•Ό ν•˜μ§€λ§Œ, 사싀 μ„œλ²„ 츑을 λΉ„λ‘―ν•œ λͺ¨λ“  ν™˜κ²½μ—μ„œ μ§€μ›ν•œλ‹€. μ§€κΈˆλΆ€ν„΄ __proto__ ν‘œκΈ°λ²•μ΄ 쑰금 더 μ§κ΄€μ μœΌλ‘œ λͺ…λ°±ν•˜λ―€λ‘œ μ˜ˆμ œμ—μ„œ μ‚¬μš©ν•  것이닀.

rabbit의 μ–΄λ–€ 속성을 μ°ΎλŠ”λ° 그것이 μ—†λ‹€λ©΄, μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” μžλ™μ μœΌλ‘œ animalμ—μ„œ 찾을 것이닀.

예λ₯Ό λ“€μ–΄:

let animal = {
  eats: true
};
let rabbit = {
  jumps: true
};

rabbit.__proto__ = animal; // (*)

// we can find both properties in rabbit now:
alert( rabbit.eats ); // true (**)
alert( rabbit.jumps ); // true

μ—¬κΈ°(*)κ°€ ν‘œμ‹œλœ μ€„μ—μ„œ rabbit의 ν”„λ‘œν† νƒ€μž…(μ›ν˜•)을 animalμ„€μ •ν•˜κ³  μžˆλ‹€.

이후, alert이 (**)μ—μ„œ rabbit.eats속성을 읽으렀 ν•  λ•Œ, rabbitμ—λŠ” ν•΄λ‹Ή 속성이 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”λ‹€. λ”°λΌμ„œ μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” [Prototype](/Lee-hyuna/33-js-concepts-kr/wiki/Prototype) μ°Έμ‘°λ₯Ό 따라가 animalμ—μ„œ ν•΄λ‹Ή 속성을 μ°Ύμ•„λ‚Έλ‹€. (μ΄λ•Œ μ•„λž˜μ„œλΆ€ν„° μ°ΎλŠ”λ‹€).

/resource/yongkwan/17/02.png

이것을 "animal은 rabbit의 ν”„λ‘œν† νƒ€μž…"라고 ν•˜κ±°λ‚˜ "rabbit은 animal으둜 λΆ€ν„° ν”„ν† λ‘œνƒ€μž… 상속을 λ°›λŠ”λ‹€."라고 ν•  수 μžˆλ‹€.

κ·Έλž˜μ„œ animal이 λ§Žμ€ μœ μš©ν•œ 속성듀과 λ©”μ†Œλ“œλ₯Ό 가지고 μžˆλ‹€λ©΄, rabbitμ—μ„œ μžλ™μœΌλ‘œ μ‚¬μš©ν•  수 있게 λœλ‹€. κ·ΈλŸ¬ν•œ 속성듀을 "inherited" 라고 λΆ€λ₯Έλ‹€.

animal에 νŠΉμ • λ©”μ†Œλ“œκ°€ μ‘΄μž¬ν•˜λ©΄, rabbitμ—μ„œλ„ ν˜ΈμΆœν•  수 μžˆλ‹€.:

let animal = {
  eats: true,
  walk() {
    alert("Animal walk");
  }
};

let rabbit = {
  jumps: true,
  __proto__: animal
};

// walk is taken from the prototype
rabbit.walk(); // Animal walk

μ•„λž˜μ™€ 같이, ν•΄λ‹Ή λ©”μ„œλ“œ(walk)λŠ” μžλ™μ μœΌλ‘œ ν”„λ‘œν† νƒ€μž…μ—μ„œ 가져와진닀.

/resource/yongkwan/17/03.png

μ΄λŸ¬ν•œ ν˜„μƒμ„ ν”„λ‘œν† νƒ€μž… 체인이라 ν•˜λŠ”λ°, ν”„λ‘œν† νƒ€μž… 체인은 더 κΈΈμ–΄μ§ˆ 수 μžˆλ‹€.

let animal = {
  eats: true,
  walk() {
    alert("Animal walk");
  }
};

let rabbit = {
  jumps: true,
  __proto__: animal
};

let longEar = {
  earLength: 10,
  __proto__: rabbit
};

// walk is taken from the prototype chain
longEar.walk(); // Animal walk
alert(longEar.jumps); // true (from rabbit)

/resource/yongkwan/17/04.png

단, λ‘κ°€μ§€μ˜ μ œμ•½μ‚¬ν•­μ΄ μžˆλ‹€.

  1. μ°Έμ‘°λŠ” μˆœν™˜μ΄ λ˜μ–΄μ„  μ•ˆλœλ‹€. __proto__λ₯Ό μˆœν™˜ν•˜λ„λ‘ ν• λ‹Ήν•˜λ©΄ μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 였λ₯˜λ₯Ό 던질 것이닀.
  2. __proto__의 값은 κ°μ²΄μ΄κ±°λ‚˜ null μ΄μ–΄μ•Όν•œλ‹€. μ›μ‹œ κ°’κ³Ό 같은 λ‹€λ₯Έ νƒ€μž…λ“€μ€ λ¬΄μ‹œλœλ‹€.

λ˜ν•œ λ‹Ήμ—°ν•˜κ²Œλ„ [Prototype](/Lee-hyuna/33-js-concepts-kr/wiki/Prototype)은 였직 ν•œκ°œλ§Œ κ°€μ§ˆ 수 μžˆλ‹€. ν•œ κ°μ²΄λŠ” λ‘κ°œμ˜ κ°μ²΄μ—μ„œ λ™μ‹œμ— 상속 받을 수 μ—†λ‹€.

값을 μ“°λŠ” 것에 ν”„λ‘œν† νƒ€μž…μ„ μ‚¬μš©ν•˜μ§€ μ•ŠκΈ°

ν”„λ‘œν† νƒ€μž…μ€ 읽기 μ „μš© 속성이닀.

κ·ΈλŸ¬λ‚˜ 속성을 μ“°κ³ /μ½λŠ” 연산은 객체에 μ§μ ‘μ μœΌλ‘œ μ μš©ν•  수 μžˆλ‹€.

μ•„λž˜μ˜ 예λ₯Ό 보면, walk λ©”μ†Œλ“œλ₯Ό rabbit에 ν• λ‹Ήν•˜κ³  μžˆλ‹€.

let animal = {
  eats: true,
  walk() {
    /* this method won't be used by rabbit */
  }
};

let rabbit = {
  __proto__: animal
};

rabbit.walk = function() {
  alert("Rabbit! Bounce-bounce!");
};

rabbit.walk(); // Rabbit! Bounce-bounce!

이제, rabbit.walk()의 ν˜ΈμΆœμ€ ν”„λ‘œν† νƒ€μž…μ„ μ‚¬μš©ν•˜μ§€ μ•Šκ³  κ°μ²΄μ—μ„œ μ¦‰μ‹œ μ°Ύμ•„μ Έ 싀행될 것이닀.

/resource/yongkwan/17/05.png

μ΄λŠ” 데이터 μ†μ„±λ§Œμ„ μœ„ν•œ 것이지 μ ‘κ·Όμžλ₯Ό μœ„ν•œ 것은 μ•„λ‹ˆλ‹€. 속성이 getter/setter 라면 ν•¨μˆ˜μ²˜λŸΌ λ™μž‘ν•œλ‹€. getter/setterλŠ” ν”„λ‘œν† νƒ€μž…μ„ 바라본닀.

그런 이유둜, admin.fullName은 μ•„λž˜ μ½”λ“œμ™€ 같이 μ •μƒμ μœΌλ‘œ λ™μž‘ν•œλ‹€.

let user = {
  name: "John",
  surname: "Smith",

  set fullName(value) {
    [this.name, this.surname] = value.split(" ");
  },

  get fullName() {
    return `${this.name} ${this.surname}`;
  }
};

let admin = {
  __proto__: user,
  isAdmin: true
};

alert(admin.fullName); // John Smith (*)

// setter triggers!
admin.fullName = "Alice Cooper"; // (**)

(*)라인의 admin.fullName속성은 user ν”„λ‘œν† νƒ€μž…μ—μ„œ getterλ₯Ό 가지고 μžˆλ‹€, κ·Έλž˜μ„œ 호좜된 것이닀. 그리고 (**)라인의 속성은 ν”„λ‘œν† νƒ€μž…μ—μ„œ setterλ₯Ό 가지고 μžˆλ‹€. λ•Œλ¬Έμ— 호좜된 것이닀.

"this" κ°’

μœ„μ˜ μ˜ˆμ œμ—μ„œ ν₯미둜운 질문이 λ‚˜μ˜¬ 수 μžˆλ‹€: set fullName(valuie)μ—μ„œ thisλŠ” μ–΄λ–€ 값을 가지고 μžˆμ„κΉŒ? μ½”λ“œ 상 μ–΄λŠ μœ„μΉ˜μ—μ„œ this.nameκ³Ό this.surname은 μ“°μ—¬μ‘Œμ„κΉŒ? user λ˜λŠ” admin? 닡은 κ°„λ‹¨ν•˜λ‹€.

thisλŠ” ν”„λ‘œν† νƒ€μž…μ— μ˜ν•΄ μ „ν˜€ 영ν–₯을 받지 μ•ŠλŠ”λ‹€.

λ©”μ„œλ“œκ°€ μ–΄λ””μ„œ 발견 λ˜λ˜κ°„μ—, λ©”μ„œλ“œ ν˜ΈμΆœμ—μ„œ thisλŠ” μ–Έμ œλ‚˜ . μ—°μ‚° μ•žμ— μžˆλŠ” 객체λ₯Ό κ°€λ₯΄ν‚¨λ‹€.

κ·Έλž˜μ„œ, setterκ°€ admin.fullName=λ₯Ό ν˜ΈμΆœν•  λ•Œ userκ°€ μ•„λ‹Œ admin을 this둜 μ‚¬μš©ν•œλ‹€.

이건 사싀 맀우 맀우 μ€‘μš”ν•œ 사싀이닀. μ™œλƒν•˜λ©΄ λ§Žμ€ λ©”μ†Œλ“œλ₯Ό 가진 객체λ₯Ό 가지고 있고 이 객체λ₯Ό 상속받은 객체가 μ‘΄μž¬ν•œλ‹€κ³  μƒκ°ν•΄λ³΄μž. κ·Έ 후에 λΆ€λͺ¨ 객체의 λ©”μ†Œλ“œλ₯Ό μƒμ†λœ κ°μ²΄μ—μ„œ μ‹€ν–‰ν•œλ‹€λ©΄, λΆ€λͺ¨ 객체의 μƒνƒœκ°’μ΄ μ•„λ‹Œ 상속 객체의 μƒνƒœ 값을 μˆ˜μ •ν•  것이닀,

예λ₯Ό λ“€μ–΄, animalκ°€ "λ©”μ†Œλ“œ μ €μž₯μ†Œ"라고 κ°€μ •ν•˜κ³ , rabbit은 이것을 μ‚¬μš©ν•œλ‹€ 치자.

rabbit.sleep()ν˜ΈμΆœμ€ this.isSleeping을 rabbit객체에 ν• λ‹Ήν•  것이닀.

// animal has methods
let animal = {
  walk() {
    if (!this.isSleeping) {
      alert(`I walk`);
    }
  },
  sleep() {
    this.isSleeping = true;
  }
};

let rabbit = {
  name: "White Rabbit",
  __proto__: animal
};

// modifies rabbit.isSleeping
rabbit.sleep();

alert(rabbit.isSleeping); // true
alert(animal.isSleeping); // undefined (no such property in the prototype)

κ²°κ³ΌλŠ” κ·Έλ¦Όκ³Ό κ°™λ‹€.

/resource/yongkwan/17/06.png

animal둜 λΆ€ν„° μƒμ†ν•œ birdλ‚˜ snake λ“±μ˜ 객체λ₯Ό 가지고 μžˆλ‹€κ³  κ°€μ •ν•΄λ³΄μž. 이 것듀도 μ—­μ‹œ animal의 λ©”μ†Œλ“œλ“€μ— μ ‘κ·Όν•  수 μžˆμ„ 것이닀. ν•˜μ§€λ§Œ 각 λ©”μ†Œλ“œμ˜ thisλŠ” animal이 μ•„λ‹ˆλΌ . 이전에 호좜 μ‹œμ μ— ν‰κ°€λœ 각 객체에 λŒ€μ‘ν•  것이닀. κ·Έλž˜μ„œ this에 데이터λ₯Ό μ €μž₯ν• λ•Œ, 이 객체듀에 μ €μž₯ν•˜λŠ” 것이닀.

결과적으둜 λ©”μ†Œλ“œλŠ” κ³΅μœ λ˜μ§€λ§Œ, 객체의 μƒνƒœ 값은 κ³΅μœ λ˜μ§€ μ•ŠλŠ”λ‹€.

for…in loop

for..in은 상속받은 속성듀도 μˆœν™˜ν•œλ‹€.

예λ₯Ό λ“€μ–΄:

let animal = {
  eats: true
};

let rabbit = {
  jumps: true,
  __proto__: animal
};

// Object.keys only return own keys
alert(Object.keys(rabbit)); // jumps

// for..in loops over both own and inherited keys
for(let prop in rabbit) alert(prop); // jumps, then eats

μ›ν•˜λŠ” κ²°κ³Όκ°€ 이것이 아닐 것이닀. 상속 받은 속성을 μ œμ™Έν•˜κ³  싢을 것이닀. 이λ₯Ό μœ„ν•œ λ‚΄μž₯ λ©”μ„œλ“œ obj.hasOwnProperty(key)κ°€ μžˆλ‹€. 이 λ©”μ„œλ“œλŠ” 속성 이름 keyκ°€ objκ°€ 가진 속성이면 (상속 받은 것이 μ•„λ‹ˆλΌ), trueλ₯Ό λ°˜ν™˜ν•œλ‹€.

λ”°λΌμ„œ μƒμ†λœ 속성듀을 κ±ΈλŸ¬λ‚Ό 수 μžˆλ‹€.

let animal = {
  eats: true
};

let rabbit = {
  jumps: true,
  __proto__: animal
};

for(let prop in rabbit) {
  let isOwn = rabbit.hasOwnProperty(prop);

  if (isOwn) {
    alert(`Our: ${prop}`); // Our: jumps
  } else {
    alert(`Inherited: ${prop}`); // Inherited: eats
  }
}

λ‹€μŒκ³Ό 같은 상속 체인이 μžˆλ‹€. rabbit은 animal을 상속 λ°›κ³  animal은 Obejct.prototype으둜 λΆ€ν„° 상속 받은 것이닀. μ™œλƒν•˜λ©΄ 기본적으둜, animal은 λ¦¬ν„°λŸ΄ 객체 {...} 이기 λ•Œλ¬Έμ΄λ‹€. 그리고 Obejct.prototype은 null을 바라본닀.

/resource/yongkwan/17/07.png

μ—¬κΈ°μ—μ„œ μž¬λ―ΈμžˆλŠ” 점이 μžˆλ‹€. rabbit.hasOwnPropertyλŠ” μ–΄λ””μ„œ λ‚˜μ˜¨ κ²ƒμΌκΉŒ? μš°λ¦¬λŠ” ν•΄λ‹Ή λ©”μ„œλ“œλ₯Ό μ •μ˜ν•˜μ§€ μ•Šμ•˜λ‹€. 상속 체인을 보면, Object.prototype.hasOwnProperty에 μ˜ν•΄ 제곡된 λ©”μ„œλ“œμž„μ„ μ•Œ 수 μžˆλ‹€. 즉, 이건 상속 받은 것이닀.

κ·ΈλŸ¬λ‚˜ μƒμ†λœ 속성듀도 λ‚˜μ—΄ν•˜λŠ” for..in λ°˜λ³΅μ—μ„œ, μ™œ eats μ΄λ‚˜ jumps처럼 hasOwnPropertyκ°€ 보이지 μ•Šμ„κΉŒ?

닡은 κ°„λ‹¨ν•˜λ‹€. hasOwnPropertyλŠ” μ—΄κ±°κ°€λŠ₯(enumerable)ν•œ 속성이 μ•„λ‹ˆκΈ° λ•Œλ¬Έμ΄λ‹€. 이와 같이 Object.prototype속성듀은 enumerable:false 값을 가지고 μžˆλ‹€. 이게 λ°”λ‘œ λ°˜λ³΅μ—μ„œ 보이지 μ•ŠλŠ” μ΄μœ μ΄λ‹€.

λͺ¨λ“  λ‹€λ₯Έ 반볡 λ©”μ†Œλ“œλ“€μ€ 상속 속성을 λ¬΄μ‹œν•œλ‹€

Object.keys, Object.values와 같은 key / valueλ₯Ό κ°€μ Έμ˜€λŠ” λ©”μ„œλ“œλ“€μ€ μƒμ†λœ 값을 λ¬΄μ‹œν•œλ‹€.

이듀은 였직 객체 μžμ²΄κ°€ 가진 값을 κ°€μ Έμ˜¨λ‹€,

μš”μ•½

  • μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ, λͺ¨λ“  κ°μ²΄λŠ” μˆ¨κ²¨μ§„ [Prototype](/Lee-hyuna/33-js-concepts-kr/wiki/Prototype)속성을 κ°–λŠ”λ‹€. 그리고 이 속성은 λ˜λ‹€λ₯Έ κ°μ²΄μ΄κ±°λ‚˜ null이닀.
  • obj.__proto__λ₯Ό μ‚¬μš©ν•˜μ—¬ 이 속성에 μ ‘κ·Όν•  수 μžˆλ‹€.
  • [Prototype](/Lee-hyuna/33-js-concepts-kr/wiki/Prototype)에 μ˜ν•΄ μ°Έμ‘°λ˜λŠ” 객체λ₯Ό "ν”„λ‘œν† νƒ€μž…(μ›ν˜•)"이라고 ν•œλ‹€.
  • obj의 속성을 μ½κ±°λ‚˜ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜κ³  싢은데 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄, μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” ν”„λ‘œν† νƒ€μž…μ—μ„œ 그것을 찾으렀 ν•  것이닀.
  • 읽기/μ§€μš°κΈ° 연산은 객체에 μ§μ ‘μ μœΌλ‘œ μ μš©λœλ‹€. ν”„λ‘œν† νƒ€μž…μ„ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€.(setterκ°€ μ•„λ‹Œ 데이터 속성이라 κ°€μ •ν–ˆμ„ 경우).
  • obj.method()λ₯Ό ν˜ΈμΆœν•˜κ³ , ν•΄λ‹Ή methodκ°€ ν”„λ‘œν† νƒ€μž…μ—μ„œ κ°€μ Έμ˜¨ 것이라면, thisλŠ” μ—¬μ „νžˆ objλ₯Ό 킨닀. 심지어 λ©”μ†Œλ“œλ“€μ΄ 상속됬닀 ν•˜λ”λΌλ„ λ©”μ†Œλ“œλ“€μ„ μ–Έμ œλ‚˜ ν˜„μž¬ 객체에 적용될 κ²ƒμž…λ‹ˆλ‹€.
  • for..in λ£¨ν”„λŠ” μžμ‹ μ˜ κ°’κ³Ό μƒμ†λœ 값을 λ°˜λ³΅ν•œλ‹€. κ·Έ μ™Έμ˜ key/valueλ₯Ό κ°€μ Έμ˜€λŠ” λ‹€λ₯Έ λͺ¨λ“  λ©”μ†Œλ“œλ“€μ€ 였직 κ·Έ μžμ‹ μ˜ 객체의 μ†μ„±λ§Œ κ°€μ Έμ˜¨λ‹€.