OOP

vagabondmsยท2021๋…„ 2์›” 26์ผ
0
post-thumbnail

ํƒœ์ดˆ์— ์ ˆ์ฐจ์  ์–ธ์–ด๊ฐ€ ์žˆ์—ˆ๋‹ค.

๋‹ค๋งŒ ์ ˆ์ฐจ์  ์–ธ์–ด๋Š” ๋ฒˆ์—ญ์ƒ์˜ ์˜ค๋ฅ˜๊ฐ€ ๊ตณ์–ด์ง„ ํ‘œํ˜„๋ฒ•์ด๋ผ๊ณ  ํ•œ๋‹ค.
Procedural Programming์ด๋ผ๋Š” ๋‹จ์–ด์—์„œ prcedural์˜ `procedure๋ฅผ ์ ˆ์ฐจ๋กœ ๋ฒˆ์—ญํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ธ๋ฐ, prcedure๋Š” c์—์„œ ํ•จ์ˆ˜๋ฅผ ์˜๋ฏธํ•˜๋ฉฐ, ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ํ†ตํ•œ ์ถ”์ƒํ™”์™€ ์žฌ์‚ฌ์šฉ์„ฑ์„ ์–ป๊ธฐ ๋•Œ๋ฌธ์— procedural programming์ด ๋œ ๊ฒƒ์ด๋ผ๊ณ  ํ•œ๋‹ค. ๊ฒฐ๋ก ์ ์œผ๋กœ ๋งํ•˜์ž๋ฉด ๋ชจ๋“  ์–ธ์–ด๋Š” ์ ˆ์ฐจ์ ์ด๊ธฐ ๋•Œ๋ฌธ์— '์ ˆ์ฐจ์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ'์ด๋ผ๋Š” ๋ง์€ ์ข‹์ง€ ์•Š์€ ๊ตฌ๋ถ„๋ฒ•์œผ๋กœ ๋ณด์ธ๋‹ค.
<์ฐธ๊ณ : https://namu.wiki/w/์ ˆ์ฐจ์ %20ํ”„๋กœ๊ทธ๋ž˜๋ฐ>


์ ˆ์ฐจ์  ์–ธ์–ด์™€ ๊ฐ์ฒด ์ง€ํ–ฅ์–ธ์–ด๋ฅผ ๋‚˜๋ˆ„์‹œ์—ˆ๋‹ค.

์ •์˜:
๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(์˜์–ด: Object-Oriented Programming, OOP)์€ ์ปดํ“จํ„ฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ํŒจ๋Ÿฌ๋‹ค์ž„ ์ค‘ ํ•˜๋‚˜์ด๋‹ค. ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ์ปดํ“จํ„ฐ ํ”„๋กœ๊ทธ๋žจ์„ ๋ช…๋ น์–ด์˜ ๋ชฉ๋ก์œผ๋กœ ๋ณด๋Š” ์‹œ๊ฐ์—์„œ ๋ฒ—์–ด๋‚˜ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋…๋ฆฝ๋œ ๋‹จ์œ„, ์ฆ‰ "๊ฐ์ฒด"๋“ค์˜ ๋ชจ์ž„์œผ๋กœ ํŒŒ์•…ํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ฐ๊ฐ์˜ ๊ฐ์ฒด๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ์ฃผ๊ณ ๋ฐ›๊ณ , ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
<์ถœ์ฒ˜ - https://ko.wikipedia.org/wiki/๊ฐ์ฒด_์ง€ํ–ฅ_ํ”„๋กœ๊ทธ๋ž˜๋ฐ>

https://jeong-pro.tistory.com/95 ์—ฌ๊ธฐ๋„ ์ฐธ๊ณ ํ• ๋งŒ ํ•˜๋‹ค


ํด๋ž˜์Šค

์–ด๋–ค ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์ถ”์ƒํ™”๋ฅผ ๊ฑฐ์ณ ์ง‘๋‹จ์— ์†ํ•˜๋Š” ์†์„ฑ/property๊ณผ ํ–‰์œ„๋ฅผ ๋ณ€์ˆ˜์™€ ๋ฉ”์„œ๋“œ๋กœ ์ •์˜ํ•œ ๊ฒƒ

์ฐธ๊ณ  :
๊ฐ์ฒด ๋‚ด์—๋Š” ๋ฐ์ดํ„ฐ์™€ ๊ธฐ๋Šฅ์— ๋Œ€์‘ํ•˜๋Š” ์†์„ฑ๊ณผ ๋ฉ”์†Œ๋“œ๊ฐ€ ์กด์žฌํ•œ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด, ๋ชจ๋“  ์ž๋™์ฐจ๋Š” ๊ณตํ†ต์ ์ธ ๊ธฐ๋Šฅ๊ณผ ๊ณ ์œ ์˜ ์†์„ฑ์ด ์žˆ๋‹ค. ๊ฐ€์†, ๊ฐ์†, ์ฃผ์œ  ๋”์ด ๊ธฐ๋Šฅ๊ณผ ์ƒ‰์ƒ, ์ตœ๊ณ  ์†๋ ฅ, ํƒ‘์Šน์ธ์›๊ณผ ๊ฐ™์€ ๊ณ ์œ ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์กด์žฌํ•œ๋‹ค.


  • ํด๋ž˜์Šค๋Š”, ์„ธ๋ถ€ ์‚ฌํ•ญ์ด(์†์„ฑ/property)์ด ๋“ค์–ด๊ฐ€์ง€ ์•Š์€ ์ฒญ์‚ฌ์ง„์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์„ธ๋ถ€ ์‚ฌํ•ญ(์†์„ฑ/property)๋งŒ ์ •ํ•ด์ค€๋‹ค๋ฉด ๊ฐ์ฒด๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค. ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด ๋งŒ๋“ค์–ด์ง„ ๊ฐ์ฒด๋ฅผ ํŠน๋ณ„ํžˆ ์ธ์Šคํ„ด์Šค๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.
  • ์ƒ์„ฑ์ž๋Š” ํด๋ž˜์Šค์— ์„ธ๋ถ€ ์‚ฌํ•ญ(์†์„ฑ/property)์„ ๋„ฃ์–ด์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. (ํ•จ์ˆ˜์— ์ธ์ž๋ฅผ ๋„ฃ๋“ฏ, ์ƒ์„ฑ์ž๋Š” ์†์„ฑ์„ ํด๋ž˜์Šค์— ๋„ฃ๋Š”๋‹ค.)

์ธ์Šคํ„ด์Šค

ํด๋ž˜์Šค์—์„œ ์ •์˜ํ•œ ๊ฒƒ์„ ํ† ๋Œ€๋กœ ์‹ค์ œ ๋ฉ”๋ชจ๋ฆฌ์ƒ์— ํ• ๋‹น๋œ ๊ฒƒ์œผ๋กœ ์‹ค์ œ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ


๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ 4๊ฐ€์ง€ ๊ธฐ๋ณธ ์ปจ์…‰

  • ์บก์Šํ™”

๋น„์Šทํ•œ ์—ญํ• ์„ ํ•˜๋Š” ์†์„ฑ๊ณผ ๋ฉ”์†Œ๋“œ๋“ค์„ ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๋กœ ๋ชจ์€ ๊ฒƒ์„ ์บก์Šํ™”๋ผ๊ณ  ํ•œ๋‹ค. ์ด ์บก์Šํ™”์˜ ๋ชฉ์ ์€ ์ฝ”๋“œ๋ฅผ ์žฌ์ˆ˜์ • ์—†์ด ์žฌํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

๋˜ํ•œ ์บก์Šํ™”์˜ ์ธก๋ฉด ์ค‘ ์€๋‹‰ํ™”๋„ ์žˆ๋‹ค.
์€๋‹‰ํ™”๋Š” ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ๋‚˜ ๋™์ž‘์ด ์™ธ๋ถ€๋กœ ๋…ธ์ถœ๋˜์ง€ ์•Š๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ์ด๋‹ค.
์•„๋ž˜๋Š” ์€๋‹‰ํ™”์˜ ์˜ˆ์‹œ๋‹ค.
๊ฐ๊ฐ ํด๋กœ์ €์™€ ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด์„œ ๊ตฌํ˜„ํ•œ ๊ฒƒ์ด๋‹ค.

< ํด๋กœ์ € >

// ํด๋กœ์ €๋ฅผ ํ†ตํ•ด ๊ตฌํ˜„ํ•œ ์€๋‹‰ํ™”์˜ ์˜ˆ์‹œ
function makeCounter() {
  let value = 0
  return {
    increase: function() {
      value++ // ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ์„ ํ•  ๊ฒฝ์šฐ, this๋Š” makeCounter ํ•จ์ˆ˜๊ฐ€ ๋ฆฌํ„ดํ•˜๋Š” ์ต๋ช…์˜ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค
    },
    decrease: function() {
      value--
    },
    getValue: function() {
      return value;
    }
  }
}

let counter1 = makeCounter()
counter1.increase()
counter1.getValue() // 1

let counter2 = makeCounter()
counter2.decrease()
counter2.decrease()
counter2.getValue() // -2

< ํด๋ž˜์Šค >

class Counter {
  constructor() {
    this.value = 0;
  }

  increase() {
    this.value++;
  }

  decrease() {
    this.value--;
  }

  getValue() {
    return this.value;
  }
}

let counter1 = new Counter()
counter1.increase()
counter1.getValue() // 1
counter1.value // 1: ์ ‘๊ทผ๊ฐ€๋Šฅ

let counter2 = new Counter()
counter2.decrease()
counter2.decrease()
counter2.getValue() // -2
counter2.value // 2: ์ ‘๊ทผ๊ฐ€๋Šฅ
  • ์ƒ์†

    ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ํŠน์ง•์„ ์ž์‹ ํด๋ž˜์Šค๊ฐ€ ๋ฌผ๋ ค ๋ฐ›๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.
    ์ฆ‰ ๊ธฐ๋ณธ ํด๋ž˜์Šค(base class)์˜ ํŠน์ง•์„ ํŒŒ์ƒํด๋ž˜์Šค(derive class)๊ฐ€ ์ƒ์† ๋ฐ›๋Š”๋‹ค.

  • ์ถ”์ƒํ™”

    ๋‚ด๋ถ€ ๊ตฌํ˜„์€ ๋ณต์žกํ•œ๋ฐ, ์‹ค์ œ๋กœ ๋…ธ์ถœ๋˜๋Š” ๋ถ€๋ถ„์€ ๋‹จ์ˆœํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค๋Š” ๊ฐœ๋…์ด๋‹ค.
    ์ฆ‰ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ๋ฉ”์†Œ๋“œ ๋“ฑ์„ ๋…ธ์ถœ์‹œํ‚ค์ง€ ์•Š๊ณ , ๋‹จ์ˆœํ•œ ์ด๋ฆ„์œผ๋กœ ์ •์˜ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

  • ๋‹คํ˜•์„ฑ

    ๊ฐ™์€ base class์—์„œ ์ƒ์† ๋ฐ›์€ ๋ฉ”์†Œ๋“œ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ ๊ฐ์ฒด ์•ˆ์—์„œ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ


์ฐธ๊ณ  ํ•  ๋งŒํ•œ ์ž๋ฃŒ


๐Ÿคฌ Prototype


Prototype์ด๋ž€

JavaScript๋Š” Java, C++ ๊ฐ™์€ ํด๋ž˜์Šค ๊ธฐ๋ฐ˜ ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์™€๋Š” ๋‹ค๋ฅด๊ฒŒ, ํ”„๋กœํ† ํƒ€์ž… ๊ธฐ๋ฐ˜ ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋ชจ๋“  ๊ฐ์ฒด๋Š” ๋ถ€๋ชจ ์—ญํ• ์„ ๋‹ด๋‹นํ•˜๋Š” ๊ฐ์ฒด์™€ ์—ฐ๊ฒฐ ๋˜์–ด์žˆ๋‹ค. ์ด๋กœ ์ธํ•ด ๋ถ€๋ชจ ๊ฐ์ฒด์˜ property๋‚˜ method๋ฅผ ์ƒ์†๋ฐ›์•„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. ์ด๋Ÿฌํ•œ ๋ถ€๋ชจ ๊ฐ์ฒด๋ฅผ 'Prototye ๊ฐ์ฒด' ๋˜๋Š” 'Prototype'์ด๋ผ๊ณ  ํ•œ๋‹ค.

์œ„ ์‚ฌ์ง„์„ ๋ณด๋ฉด instance์ธ me์˜ __proto__ ์•ˆ์— prototype ๊ฐ์ฒด๊ฐ€ ๋“ค์–ด๊ฐ€ ์žˆ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.(์ •ํ™•ํ•˜๊ฒŒ ์ด์•ผ๊ธฐ ํ•˜๋ฉด ์ž์‹ ์˜ ๋ถ€๋ชจ ๊ฐ์ฒด(prototype ๊ฐ์ฒด)์ธ CallName.prototype์„ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋‹ค.)

__proto__vs .prototype

์ด ๋‘˜์ด ์กฐ๊ธˆ ํ—ท๊ฐˆ๋ ค์„œ ์ •๋ฆฌํ•˜๊ณ  ๋„˜์–ด๊ฐ€์•ผ๊ฒ ๋‹ค.
์ „์ž๋Š” ๋ชจ๋“  ๊ฐ์ฒด๋Š” [[Prototype]]์ด๋ผ๋Š” internal slot์„ ๊ฐ–๊ฒŒ ๋˜๋ฉฐ, ์ด๋Š” ์ƒ์†์„ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค. ๋˜ํ•œ ์ด๋Š” __proto__ ํ”„๋กœํผํ‹ฐ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.


ํ—ˆ๋‚˜ ํ•จ์ˆ˜๋Š” [[Prototype]] ์™ธ์— ํ›„์ž์ธ .prototype ์ฆ‰, prototype ํ”„๋กœํผํ‹ฐ๋„ ๊ฐ–๊ณ  ์žˆ๋‹ค.


์ฆ‰ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • [[Prototype]]

    1) __proto___๋ฅผ ํ†ตํ•ด ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.
    2) ๋ชจ๋“  ๊ฐ์ฒด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” internal slot์ด๋‹ค.
    3) ๊ฐ์ฒด์˜ ์ž…์žฅ์—์„œ ๋ถ€๋ชจ ์—ญํ• ์„ ํ•˜๋Š” ํ”„๋กœํ†  ํƒ€์ž… ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

  • prototype ํ”„๋กœํผํ‹ฐ

    1) ํ•จ์ˆ˜ ๊ฐ์ฒด๋งŒ ๊ฐ–๊ณ  ์žˆ๋Š” ํ”„๋กœํผํ‹ฐ
    2) ํ•จ์ˆ˜ ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ์ž๋กœ ์‚ฌ์šฉ๋  ๋•Œ, ์ด ํ•จ์ˆ˜์— ์˜ํ•ด ๋งŒ๋“ค์–ด์ง„ ๊ฐ์ฒด์˜ prototype ๊ฐ์ฒด๋‹ค.

Constructor ํ”„๋กœํผํ‹ฐ


me๋ผ๋Š” ๊ฐ์ฒด์˜ constructor๋Š” ์ž์‹ ์˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋‹ค.

๋”ฐ๋ผ์„œ, me๋ผ๋Š” ๊ฐ์ฒด์˜ ํ”„๋กœํ† ํƒ€์ž… ๊ฐ์ฒด๋Š” CallName.prototype์ด๋ฉฐ,
CallName.prototype์— ์žˆ๋Š” constructor ํ”„๋กœํผํ‹ฐ๋Š” CallName() ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

old fashioned - pseudoclassical subclasses

์ด ๋ถ€๋ถ„์€ ES6 ๋ฌธ๋ฒ• ์ด์ „์— ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์—ผ๋‘ํ•˜๊ณ  ๋งŒ๋“ค์–ด์ง€์ง€ ์•Š์€ JS์—์„œ OOP๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ์‹์ด์—ˆ๋‹ค๊ณ  ํ•œ๋‹ค.
๋˜ํ•œ ES6 ์ดํ›„๋กœ๋Š” ๋งค์šฐ ๊ฐ„๋‹จํ•œ ๋ฐฉ์‹์œผ๋กœ OOP์˜ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•ด์กŒ์ง€๋งŒ ์ž‘๋™์›๋ฆฌ๋Š” ๊ฐ™๋‹ค๊ณ  ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ๊ทธ ์ž‘๋™์›๋ฆฌ์— ๋Œ€ํ•œ ์ดํ•ด๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์„ฑํ•˜์˜€๋‹ค.

let Human = function(name) { this.name = name }

Human.prototype.sleep = function() {};

let Student = function(name){};

Student.prototype.learn = function(){console.log('JS')};

let Me = new Student('KIM');
Me.learn(); // JS
Me.sleep(); // err: Me.sleep is not a function


์œ„ ์ฝ”๋“œ์—์„œ Me.sleep()์€ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ ์ด์œ ๋Š” Human ํด๋ž˜์Šค์˜ method๋ฅผ ์ „๋‹ฌ ๋ฐ›์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.


Student Class๋กœ instance๊ฐ€ Human().prototype์„ ์ƒ์† ๋ฐ›๊ฒŒ ๋งŒ๋“ค์–ด๋ณด์ž


  • #1 Me.__proto__ = Human.prototype

Me์˜ prototype ๊ฐ์ฒด๊ฐ€ Human.prototype์ด ๋˜์–ด๋ฒ„๋ ค์„œ Me.learn()์ด ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค.
์ฆ‰ Student.prototype๊ณผ์˜ ์—ฐ๊ฒฐ์ด ๋Š๊ฒจ๋ฒ„๋ ธ๋‹ค.

์ด๋Ÿฐ ํ–‰์œ„๋Š” ๊ณต์‹ ๋ฌธ์„œ์—์„œ ํ•˜์ง€ ๋ง๋ผ๊ณ  ์ง€์ •ํ–ˆ๋‹ค๊ณ  ํ•œ๋‹ค!


Warning
Stuudent.prototype.__proto__ = Human.prototype๋ฅผ ํ•˜๋ฉด, ์›ํ•˜๋Š” ๋ฐ๋กœ ์ž‘๋™ํ•˜๊ฒŒ ๋œ๋‹ค. ์ฆ‰ Student๋ฅผ ์ด์šฉํ•ด ์ƒ์„ฑ๋œ instance๊ฐ€ Human์˜ method๋ฅผ ๊ฐ–๊ฒŒ ๋œ๋‹ค.
๐Ÿคฏํ•˜์ง€๋งŒ ์„ ์ˆ ํ•˜์—ฟ๋“ฏ์ด __proto__์— ์ง์ ‘ ํ• ๋‹นํ•˜๋Š” ํ–‰์œ„๋Š” ๊ณต์‹ ๋ฌธ์„œ์—์„œ ๊ธˆ์ง€ํ•˜์˜€๋‹ค.


  • #2 Student.prototype = Human.prototype
let Human = function(name) { this.name = name }

Human.prototype.sleep = function() {};

let Student = function(name){};
Student.prototype = Human.prototype // <-- chnaged
Student.prototype.learn = function(){console.log('JS')}; // <-- changed
//์œ— ์ค„์€ Human.prototype.learn์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ํ–‰์œ„๊ฐ€ ๋œ๋‹ค.

let Me = new Student('KIM');
Me.learn(); // JS
Me.sleep(); 
  • Student.prototype = Human.prototype ์ด ๋ถ€๋ถ„๋งŒ ์‚ฝ์ž…ํ•˜๋ฉด learn์ด ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • Student.prototype.learn = function(){console.log('JS')}; ์ด ๋ถ€๋ถ„๊นŒ์ง€ ์‚ฝ์ž…ํ•˜๋ฉด learn๋„ ์ž‘๋™ํ•˜๊ฒŒ ๋˜์ง€๋งŒ, Student.prototype์ด Human.prototype ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, Student...์˜ ๊ฐ’์„ ๋ฐ”๊พธ๋ฉด Human...์˜ ๊ฐ’๋„ ๋ฐ”๋€๋‹ค.
    ๋”ฐ๋ผ์„œ Human์ด learn() method๋ฅผ ๊ฐ–๊ฒŒ ๋œ๋‹ค.๐Ÿ˜…
  • #3 Human.prototype์„ ๋ณต์‚ฌ! ๐Ÿ˜‡

1)

let Human = function(name) { this.name = name }

Human.prototype.sleep = function() {};

let Student = function(name){};
Student.prototype = Object.create(Human.prototype) // <-- chnaged
// Object.create(<prototype>)์€ ์ธ์ž๋กœ ๋“ค์–ด์˜จ prototype์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒˆ๋กœ์šด prototype์„ ๋งŒ๋“ ๋‹ค.
Student.prototype.learn = function(){console.log('JS')}; // <-- changed

let Me = new Student('KIM');
Me.learn(); // JS
Me.sleep(); 

ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ ๋ชจ๋‘ ๋๋‚œ ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.

2)


ํ˜„์žฌ Me์˜ [[Prototype]] ์•ˆ์— Constructor๊ฐ€ ์—†๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰ Student() ์ƒ์„ฑ์ž ํ•จ์ˆ˜์™€์˜ ์—ฐ๊ฒฐ๊ณ ๋ฆฌ๊ฐ€ ์‚ฌ๋ผ์กŒ๋‹ค.

์‹ฌ์ง€์–ด constructor๋ฅผ ์ฐ์–ด๋ณด๋ฉด Human() ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ, Me์™€ Student() ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์ด์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

//...์ƒ๋žต

Student.prototype = Object.create(Human.prototype) // <-- chnaged
// Object.create(<prototype>)์€ ์ธ์ž๋กœ ๋“ค์–ด์˜จ prototype์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒˆ๋กœ์šด prototype์„ ๋งŒ๋“ ๋‹ค.
Student.prototype.learn = function(){console.log('JS')}; // <-- changed
Student.prototype.constructor = Student;
//์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ Student.prototype.constructor๋กœ ์ง์ ‘ ์ง€์ •ํ•œ๋‹ค. 

//์ƒ๋žต...

3)

์•„์ง๋„ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค.

Me๋ฅผ ์ƒ์„ฑํ•  ๋•Œ, Student() ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— 'KIM'์ด๋ผ๋Š” ์ธ์ž๋ฅผ ์ „๋‹ฌํ–ˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  Human() ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•ด name property๊ฐ€ ์ƒ์„ฑ ๋˜์ง€ ์•Š๊ณ  ์žˆ๋‹ค.


//...์ƒ๋žต
let Student = function(name){
	Human.call(this,name) // Human.apply(this, arguments)// <<-- changed
};
Student.prototype = Object.create(Human.prototype) 
Student.prototype.learn = function(){console.log('JS')}; 
Student.prototype.constructor = Student;

//...์ƒ๋žต

์•„์ง ์ด ๋ถ€๋ถ„์ด ํ™•์—ฐํžˆ ์™€๋‹ฟ์ง€๋Š” ์•Š๋Š”๋‹ค.

๋‹ค๋งŒ, Student() ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ์•ˆ์— Human.call(this,name) ์ฝ”๋“œ๋กœ this์™€ name arg๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜์—ฌ ๊ฐ•์ œ๋กœ ์‹คํ–‰์‹œํ‚ค๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค.

this๋Š” instance๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ธฐ ๋•Œ๋ฌธ์—, ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š์œผ๋ฉด, Human() ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ์•ˆ์— ์žˆ๋Š” this๋Š” ๊ฐ€๋ฆฌํ‚ค๋Š” ๋Œ€์ƒ์ด ์—†๋‹ค.

์—ฌ๊ธฐ๊นŒ์ง€ ํ–ˆ๋‹ค๋ฉด ๋“œ๋””์–ด ์™„์„ฑ์ด๋‹ค......๐Ÿคฌ๐Ÿคฏ๐Ÿคฌ๐Ÿคฏ๐Ÿคฌ๐Ÿคฏ

๋‹คํ˜•์„ฑ์„ ๋งŒ์กฑ์‹œํ‚ค๊ธฐ ์œ„ํ•ด... ํ•˜๋‚˜๋ฅผ ...๋”...

๋งŒ์•ฝ ์œ„์˜ ์˜ˆ์‹œ์—์„œ Student.prototype ์•ˆ์— sleep์ด๋ผ๋Š” method๋ฅผ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ณด์ž.

๋‹จ, ๊ธฐ์กด์˜

Human.prototype.sleep = function(){
	console.log('zzz')
})

์ด๋ผ๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.

์ด๋•Œ, Student.prototype.sleep์„ ์‹คํ–‰์‹œ์ผฐ์„ ๋•Œ,
'zzz'๋„ ์ฝ˜์†”์— ์ฐํž ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๊ณ  ์‹ถ๋‹ค๋ฉด?

Student.prototype.sleep = function(){
  Human.prototype.sleep.apply(this)
  console.log('do not sleep!')
}

์ด๋ ‡๊ฒŒ ๋˜๋ฉด,
Student ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ ๋งŒ๋“  Instance๋“ค์—์„œ sleep method๋ฅผ ๋™์ž‘์‹œ์ผฐ์„ ๋•Œ,

'zzz'
'do not sleep!'

์ด ๋™์‹œ์— ์ฐํ˜€๋‚˜์˜จ๋‹ค.


ES6์—์„œ ์ƒ๊ธด Class๐Ÿ˜‡

class BlinkyDancerClass extends DancerClass {
  // your code here
  constructor(top, left, timeBetweenSteps){
    super(top, left, timeBetweenSteps)
    //superclass์˜ method์™€ property๋ฅผ ์ด์–ด๋ฐ›๋Š” ๋ถ€๋ถ„.
  }
  
  step(){
    super.step() //superclass์˜ step method์˜ ํŠน์„ฑ์„ ์ด์–ด๋ฐ›๋Š” ๋ถ€๋ถ„.
    let style = this.$node.style;
    style.display = style.display === 'none' ? 'inline-block' : 'none';
  }
}

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