๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ“ฐ ์–ธ์–ด/JS

๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(OOP)

์ฑ… <๋Ÿฌ๋‹์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ>๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ๋ฐฐ์šด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

 

๋ชฉ์ฐจ

  • <๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(OOP)>
    1. ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์šฉ์–ด
    2. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์–ธ์–ด์  ํŠน์ง•
  • <์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ OOP>
    1. ๊ฐ์ฒด ์ƒ์„ฑ
    2. ํด๋ž˜์Šค(ES5 vs ES6) ์ƒ์„ฑ
    3. ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
    4. construnctor(์ƒ์„ฑ์ž)  
    5. ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ๊ณผ ๋ฉ”์†Œ๋“œ ์ •์˜
    6. ์ƒ์† - ์˜์‚ฌ ํด๋ž˜์Šค ํŒจํ„ด ์ƒ์†, ํ”„๋กœํ† ํƒ€์ž… ํŒจํ„ด ์ƒ์†
    7. ์บก์Šํ™”, ์ถ”์ƒํ™”, ๋‹คํ˜•์„ฑ

 

<๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(OOP)>

1. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์–ธ์–ด์  ํŠน์ง•

  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๋ฉ€ํ‹ฐ-ํŒจ๋Ÿฌ๋‹ค์ž„ ์–ธ์–ด๋กœ ๋ช…๋ นํ˜•(imperative), ํ•จ์ˆ˜ํ˜•(functional), ํ”„๋กœํ† ํƒ€์ž… ๊ธฐ๋ฐ˜(prototype-based) ๊ฐ์ฒด์ง€ํ–ฅ ์–ธ์–ด์ด๋‹ค.
  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์ด๋ฏธ ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค์˜ ์ž๋ฃŒ๊ตฌ์กฐ์™€ ๊ธฐ๋Šฅ์„ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ํŠน์ง•์ด ์žˆ๋‹ค. ๊ฐ์ฒด ์ง€ํ–ฅ์˜ ์ƒ์†, ์บก์Šํ™”(์ •๋ณด ์€๋‹‰) ๋“ฑ์˜ ๊ฐœ๋…์€ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ๊ณผ ํด๋กœ์ € ๋“ฑ์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  •  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ํ•จ์ˆ˜ ๊ฐ์ฒด๋กœ ๋งŽ์€ ๊ฒƒ์„ ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ํด๋ž˜์Šค, ์ƒ์„ฑ์ž, ๋ฉ”์†Œ๋“œ๋„ ๋ชจ๋‘ ํ•จ์ˆ˜๋กœ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜๋‹ค.(ES6์—์„œ ์ƒˆ๋กญ๊ฒŒ Class๊ฐ€ ๋„์ž…๋˜์—ˆ์ง€๋งŒ ์ƒˆ๋กœ์šด ๊ฐ์ฒด์ง€ํ–ฅ ๋ชจ๋ธ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ฉฐ, Class๋„ ์‚ฌ์‹ค ํ•จ์ˆ˜์ด๊ณ  ๊ธฐ์กด ํ”„๋กœํ† ํƒ€์ž… ๊ธฐ๋ฐ˜์ด๋‹ค.)
  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜์™€ new ์—ฐ์‚ฐ์ž๋ฅผ ํ†ตํ•ด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋•Œ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” ํด๋ž˜์Šค์ด์ž ์ƒ์„ฑ์ž์˜ ์—ญํ• ์„ ํ•œ๋‹ค.

 

2. ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์šฉ์–ด

  • Class : ๊ฐ์ฒด์˜ ํŠน์„ฑ์„ ์ •์˜
  • Object : Class์˜ ์ธ์Šคํ„ด์Šค
  • Property : ๊ฐ์ฒด์˜ ํŠน์„ฑ(์˜ˆ: ์ƒ‰๊น”)
  • Method : ๊ฐ์ฒด์˜ ๋Šฅ๋ ฅ(์˜ˆ: ๊ฑท๊ธฐ)
  • Constructor : ์ธ์Šคํ„ด์Šคํ™” ๋˜๋Š” ์‹œ์ ์—์„œ ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์„œ๋“œ
  • Inheritance : ํด๋ž˜์Šค๋Š” ๋‹ค๋ฅธ ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ํŠน์„ฑ๋“ค์„ ์ƒ์†๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.
  • Encapsulation : ํด๋ž˜์Šค๋Š” ํ•ด๋‹น ๊ฐ์ฒด์˜ ํŠน์„ฑ๋“ค๋งŒ์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๊ณ , ๋ฉ”์„œ๋“œ๋Š” ๊ทธ ๋ฉ”์„œ๋“œ๊ฐ€ ์–ด๋–ป๊ฒŒ ์‹คํ–‰๋˜๋Š”์ง€๋งŒ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. (์™ธ๋ถ€ ์ ‘๊ทผ ๋ถˆ๊ฐ€)
  • Abstraction : ๋ณต์žกํ•œ ์ƒ์†, ๋ฉ”์„œ๋“œ, ๊ฐ์ฒด์˜ ์†์„ฑ์˜ ๊ฒฐํ•ฉ์€ ๋ฐ˜๋“œ์‹œ ํ˜„์‹ค ์„ธ๊ณ„๋ฅผ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
  • Polymorphism : ๋‹ค๋ฅธ ํด๋ž˜์Šค๋“ค์ด ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋‚˜ ์†์„ฑ์œผ๋กœ ์ •์˜๋  ์ˆ˜ ์žˆ๋‹ค.

 

<์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ OOP>

1. ๊ฐ์ฒด ์ƒ์„ฑ

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ํด๋ž˜์Šค ๊ฐœ๋…์ด ์—†๊ณ  ๋ณ„๋„์˜ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐฉ๋ฒ•์ด ์กด์žฌํ•œ๋‹ค.

// ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด
var obj1 = {};
obj1.name = 'Lee';

// Object() ์ƒ์„ฑ์ž ํ•จ์ˆ˜
var obj2 = new Object();
obj2.name = 'Lee';

// ์ƒ์„ฑ์ž ํ•จ์ˆ˜
function F() {}
var obj3 = new F();
obj3.name = 'Lee';

 

 

2. ํด๋ž˜์Šค ์ƒ์„ฑ

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ(ํ”„๋กœํ† ํƒ€์ž… ๊ธฐ๋ฐ˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ)๋Š” ํด๋ž˜์Šค๊ฐ€ ํ•„์š”์—†๋Š”(class-free) ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์Šคํƒ€์ผ๋กœ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ๊ณผ ํด๋กœ์ € ๋“ฑ์œผ๋กœ ๊ฐ์ฒด ์ง€ํ–ฅ ์–ธ์–ด์˜ ์ƒ์†, ์บก์Šํ™”(์ •๋ณด ์€๋‹‰) ๋“ฑ์˜ ๊ฐœ๋…์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

2-1) ES5(ES6์ด์ „) - ์ƒ์„ฑ์ž ํ•จ์ˆ˜์™€ ํ”„๋กœํ† ํƒ€์ž…, ํด๋กœ์ €๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๊ตฌํ˜„ํ•˜์˜€๋‹ค.

 

 

// ES5
var Person = (function () {
  // Constructor
  function Person(name) {
    this._name = name;
  }

  // public method
  Person.prototype.sayHi = function () {
    console.log('Hi! ' + this._name);
  };

  // return constructor
  return Person;
}());

var me = new Person('Lee');
me.sayHi(); // Hi! Lee.

console.log(me instanceof Person); // true

 

2-2) ES6 - ES6์—์„œ class ๋ผ๋Š” ๋ฌธ๋ฒ•์ด ์ถ”๊ฐ€ ๋˜์–ด,class ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ •์˜ํ•œ๋‹ค.  ๊ธฐ์กด์˜ prototype ๊ธฐ๋ฐ˜์œผ๋กœ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ๋ณด๋‹ค ๋ช…๋ฃŒํ•˜๊ฒŒ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

// ํด๋ž˜์Šค ์„ ์–ธ๋ฌธ
class Person {
  // constructor(์ƒ์„ฑ์ž)
  constructor(name) {
    this._name = name;
  }

  sayHi() {
    console.log(`Hi! ${this._name}`);
  }
}

// ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
const me = new Person('Lee');
me.sayHi(); // Hi! Lee

console.log(me instanceof Person); // true

โ€ปํด๋ž˜์Šค๋Š” ํด๋ž˜์Šค ์„ ์–ธ๋ฌธ ์ด์ „์— ์ฐธ์กฐํ•  ์ˆ˜ ์—†๋‹ค. ํ•˜์ง€๋งŒ, ํ˜ธ์ด์ŠคํŒ…์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ํด๋ž˜์Šค๋Š” var ํ‚ค์›Œ๋“œ๋กœ ์„ ์–ธํ•œ ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ํ˜ธ์ด์ŠคํŒ…๋˜์ง€ ์•Š๊ณ , let, const ํ‚ค์›Œ๋“œ๋กœ ์„ ์–ธํ•œ ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ํ˜ธ์ด์ŠคํŒ…๋œ๋‹ค. ๋”ฐ๋ผ์„œ ํด๋ž˜์Šค ์„ ์–ธ๋ฌธ ์ด์ „์— ์ผ์‹œ์ ์œผ๋กœ ์‚ฌ๊ฐ์ง€๋Œ€์— ๋น ์ง€๊ธฐ ๋•Œ๋ฌธ์— ํ˜ธ์ด์ŠคํŒ…์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋™์ž‘ํ•œ๋‹ค.

 

 

3. ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ : new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํด๋ž˜์Šค ์ด๋ฆ„์„ ํ˜ธ์ถœํ•˜๋ฉด ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.

class Foo {}

const foo = new Foo();

// new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•œ Foo๋Š” ํด๋ž˜์Šค์˜ ์ด๋ฆ„์ด ์•„๋‹ˆ๋ผ constructor(์ƒ์„ฑ์ž)์ด๋‹ค. 
// new ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  constructor๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด TypeError๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

 

 

4. construnctor(์ƒ์„ฑ์ž)

  • ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํด๋ž˜์Šค ํ•„๋“œ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ ์œ„ํ•œ ํŠน์ˆ˜ํ•œ ๋ฉ”์†Œ๋“œ
  • ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ new ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•œ ๊ฒƒ์ด ๋ฐ”๋กœ constructor์ด๋ฉฐ constructor์˜ ํŒŒ๋ผ๋ฏธํ„ฐ์— ์ „๋‹ฌํ•œ ๊ฐ’์€ ํด๋ž˜์Šค ํ•„๋“œ์— ํ• ๋‹นํ•œ๋‹ค.
  • constructor๋Š” ํด๋ž˜์Šค ๋‚ด์— ํ•œ ๊ฐœ๋งŒ ์กด์žฌํ•˜๊ณ , 2๊ฐœ ์ด์ƒ ์กด์žฌํ•˜๋ฉด SyntaxError ๋ฐœ์ƒํ•œ๋‹ค.
  • constructor๋Š” ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค. constructor๋ฅผ ์ƒ๋žตํ•˜๋ฉด ํด๋ž˜์Šค์— constructor() {}๋ฅผ ํฌํ•จํ•œ ๊ฒƒ๊ณผ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค. ์ฆ‰, ๋นˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์ธ์Šคํ„ด์Šค์— ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•œ ์ดํ›„, ํ”„๋กœํผํ‹ฐ๋ฅผ ๋™์ ์œผ๋กœ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.
  • constructor๋Š” ์ธ์Šคํ„ด์Šค์˜ ์ƒ์„ฑ๊ณผ ๋™์‹œ์— ํด๋ž˜์Šค ํ•„๋“œ์˜ ์ƒ์„ฑ๊ณผ ์ดˆ๊ธฐํ™”๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ํด๋ž˜์Šค ํ•„๋“œ๋ฅผ ์ดˆ๊ธฐํ™”ํ•ด์•ผ ํ•œ๋‹ค๋ฉด constructor๋ฅผ ์ƒ๋žตํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค.
// ํด๋ž˜์Šค ์„ ์–ธ๋ฌธ
class Person {
  // constructor(์ƒ์„ฑ์ž). ์ด๋ฆ„์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์—†๋‹ค.
  constructor(name) {
    // this๋Š” ํด๋ž˜์Šค๊ฐ€ ์ƒ์„ฑํ•  ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.
    // _name์€ ํด๋ž˜์Šค ํ•„๋“œ์ด๋‹ค.
    this._name = name;
  }
}

// ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
const me = new Person('Lee');
console.log(me); // Person {_name: "Lee"}

 

 

5. ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ๊ณผ ๋ฉ”์†Œ๋“œ ์ •์˜

  • ๋ชจ๋“  ๊ฐ์ฒด๋Š” ํ”„๋กœํ† ํƒ€์ž…์ด๋ผ๋Š” ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋‚ด๋ถ€ ๋งํฌ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ์ฆ‰, ํ”„๋กœํ† ํƒ€์ž…์„ ํ†ตํ•ด ์ง์ ‘ ๊ฐ์ฒด๋ฅผ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด๋ฅผ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์ด๋ผ ํ•œ๋‹ค.
  • ํ”„๋กœํ† ํƒ€์ž…์„ ์ด์šฉํ•˜์—ฌ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ๋‚ด๋ถ€์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ prototype ํ”„๋กœํผํ‹ฐ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ํ”„๋กœํ† ํƒ€์ž… ๊ฐ์ฒด๋กœ ์ด๋™์‹œํ‚ค๋ฉด ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•ด ์ƒ์„ฑ๋œ ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๋Š” ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์„ ํ†ตํ•ด ํ”„๋กœํ† ํƒ€์ž… ๊ฐ์ฒด์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค.
function Person(name) {
  this.name = name;
}

// ํ”„๋กœํ† ํƒ€์ž… ๊ฐ์ฒด์— ๋ฉ”์†Œ๋“œ ์ •์˜
Person.prototype.setName = function (name) {
  this.name = name;
};

// ํ”„๋กœํ† ํƒ€์ž… ๊ฐ์ฒด์— ๋ฉ”์†Œ๋“œ ์ •์˜
Person.prototype.getName = function () {
  return this.name;
};

var me  = new Person('Lee');
var you = new Person('Kim');
var him = new Person('choi');

console.log(Person.prototype);
// Person { setName: [Function], getName: [Function] }

console.log(me);  // Person { name: 'Lee' }
console.log(you); // Person { name: 'Kim' }
console.log(him); // Person { name: 'choi' }

 

6. ์ƒ์†(Inheritance)

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์ƒ์† ๊ตฌํ˜„ ๋ฐฉ์‹์€ ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€๋กœ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.

6-1) ์˜์‚ฌ ํด๋ž˜์Šค ํŒจํ„ด ์ƒ์†(Pseudo-classical Inheritance) - ํด๋ž˜์Šค ๊ธฐ๋ฐ˜ ์–ธ์–ด์˜ ์ƒ์† ๋ฐฉ์‹์„ ํ‰๋‚ด ๋‚ด๋Š” ๊ฒƒ

์˜์‚ฌ ํด๋ž˜์Šค ํŒจํ„ด์€ ์ž์‹ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ prototype ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ถ€๋ชจ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ ์ธ์Šคํ„ด์Šค๋กœ ๊ต์ฒดํ•˜์—ฌ ์ƒ์†์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ๋ถ€๋ชจ์™€ ์ž์‹ ๋ชจ๋‘ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜์—ฌ์•ผ ํ•œ๋‹ค.

 

 

Child ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•œ ์ธ์Šคํ„ด์Šค child(โ‘ )์˜ ํ”„๋กœํ† ํƒ€์ž… ๊ฐ์ฒด๋Š” Parent ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•œ ์ธ์Šคํ„ด์Šค(โ‘ก)์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  Parent ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•œ ์ธ์Šคํ„ด์Šค์˜ ํ”„๋กœํ† ํƒ€์ž… ๊ฐ์ฒด๋Š” Parent.prototype์ด๋‹ค.

child๋Š” ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์— ์˜ํ•ด Parent ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•œ ์ธ์Šคํ„ด์Šค์™€ Parent.prototype์˜ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

// ๋ถ€๋ชจ ์ƒ์„ฑ์ž ํ•จ์ˆ˜
var Parent = (function () {
  // Constructor
  function Parent(name) {
    this.name = name;
  }

  // method
  Parent.prototype.sayHi = function () {
    console.log('Hi! ' + this.name);
  };

  // return constructor
  return Parent;
}());

// ์ž์‹ ์ƒ์„ฑ์ž ํ•จ์ˆ˜
var Child = (function () {
  // Constructor
  function Child(name) {
    this.name = name;
  }

  // ์ž์‹ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ ํ”„๋กœํ† ํƒ€์ž… ๊ฐ์ฒด๋ฅผ ๋ถ€๋ชจ ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ ์ธ์Šคํ„ด์Šค๋กœ ๊ต์ฒด.
  Child.prototype = new Parent(); // โ‘ก

  // ๋ฉ”์†Œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋“œ
  Child.prototype.sayHi = function () {
    console.log('์•ˆ๋…•ํ•˜์„ธ์š”! ' + this.name);
  };

  // sayBye ๋ฉ”์†Œ๋“œ๋Š” Parent ์ƒ์„ฑ์žํ•จ์ˆ˜์˜ ์ธ์Šคํ„ด์Šค์— ์œ„์น˜๋œ๋‹ค
  Child.prototype.sayBye = function () {
    console.log('์•ˆ๋…•ํžˆ๊ฐ€์„ธ์š”! ' + this.name);
  };

  // return constructor
  return Child;
}());

var child = new Child('child'); // โ‘ 
console.log(child);  // Parent { name: 'child' }

console.log(Child.prototype); // Parent { name: undefined, sayHi: [Function], sayBye: [Function] }

child.sayHi();  // ์•ˆ๋…•ํ•˜์„ธ์š”! child
child.sayBye(); // ์•ˆ๋…•ํžˆ๊ฐ€์„ธ์š”! child

console.log(child instanceof Parent); // true
console.log(child instanceof Child);  // true

โ€ป ์˜์‚ฌ ํด๋ž˜์Šค ํŒจํ„ด์˜ ๋ฌธ์ œ์ (๊ตฌ๋™ ์ƒ์— ๋ฌธ์ œ๋Š” ์—†๋‹ค.)

new ์—ฐ์‚ฐ์ž๋ฅผ ํ†ตํ•ด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑ :  ํ”„๋กœํ† ํƒ€์ž… ๋ณธ์„ฑ์— ๋งž๊ฒŒ ๊ฐ์ฒด์—์„œ ๋‹ค๋ฅธ ๊ฐ์ฒด๋กœ ์ง์ ‘ ์ƒ์†ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ฐ–๋Š” ๋Œ€์‹  ์ƒ์„ฑ์ž ํ•จ์ˆ˜์™€ new ์—ฐ์‚ฐ์ž๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ถˆํ•„์š”ํ•œ ๊ฐ„์ ‘์ ์ธ ๋‹จ๊ณ„๊ฐ€ ์žˆ๋‹ค. 

 

6-2) ํ”„๋กœํ† ํƒ€์ž… ํŒจํ„ด ์ƒ์†(Prototypal Inheritance) - ํ”„๋กœํ† ํƒ€์ž…์œผ๋กœ ์ƒ์†์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ

ํ”„๋กœํ† ํƒ€์ž… ํŒจํ„ด ์ƒ์†์€ Object.create ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด์—์„œ ๋‹ค๋ฅธ ๊ฐ์ฒด๋กœ ์ง์ ‘ ์ƒ์†์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ํ”„๋กœํ† ํƒ€์ž… ํŒจํ„ด ์ƒ์†์€ ๊ฐœ๋…์ ์œผ๋กœ ์˜์‚ฌ ํด๋ž˜์Šค ํŒจํ„ด ์ƒ์†๋ณด๋‹ค ๋” ๊ฐ„๋‹จํ•˜๋‹ค. ๋˜ํ•œ ์˜์‚ฌ ํด๋ž˜์Šค ํŒจํ„ด์˜ ๋‹จ์ ์ธ new ์—ฐ์‚ฐ์ž๊ฐ€ ํ•„์š”์—†์œผ๋ฉฐ, ์ƒ์„ฑ์ž ๋งํฌ๋„ ํŒŒ๊ดด๋˜์ง€ ์•Š์œผ๋ฉฐ, ๊ฐ์ฒด๋ฆฌํ„ฐ๋Ÿด์—๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

# ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ ํ”„๋กœํ† ํƒ€์ž… ํŒจํ„ด ์ƒ์†
// ๋ถ€๋ชจ ์ƒ์„ฑ์ž ํ•จ์ˆ˜
var Parent = (function () {
  // Constructor
  function Parent(name) {
    this.name = name;
  }

  // method
  Parent.prototype.sayHi = function () {
    console.log('Hi! ' + this.name);
  };

  // return constructor
  return Parent;
}());

// create ํ•จ์ˆ˜์˜ ์ธ์ˆ˜๋Š” ํ”„๋กœํ† ํƒ€์ž…์ด๋‹ค.
var child = Object.create(Parent.prototype);
child.name = 'child';

child.sayHi();  // Hi! child

console.log(child instanceof Parent); // true

๊ฐ์ฒด๋ฆฌํ„ฐ๋Ÿด ํŒจํ„ด์œผ๋กœ ์ƒ์„ฑํ•œ ๊ฐ์ฒด์—๋„ ํ”„๋กœํ† ํƒ€์ž… ํŒจํ„ด ์ƒ์†์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

var parent = {
  name: 'parent',
  sayHi: function() {
    console.log('Hi! ' + this.name);
  }
};

// create ํ•จ์ˆ˜์˜ ์ธ์ž๋Š” ๊ฐ์ฒด์ด๋‹ค.
var child = Object.create(parent);
child.name = 'child';

// var child = Object.create(parent, {name: {value: 'child'}});

parent.sayHi(); // Hi! parent
child.sayHi();  // Hi! child

console.log(parent.isPrototypeOf(child)); // true

 

 

7. ์บก์Šํ™”, ์ถ”์ƒํ™”, ๋‹คํ˜•์„ฑ

7-1) ์บก์Šํ™”(Encapsulation)
์บก์Šํ™”๋Š” ๊ด€๋ จ์žˆ๋Š” ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์™€ ๋ฉ”์†Œ๋“œ๋ฅผ ํด๋ž˜์Šค์™€ ๊ฐ™์€ ํ•˜๋‚˜์˜ ํ‹€ ์•ˆ์— ๋‹ด๊ณ  ์™ธ๋ถ€์— ๊ณต๊ฐœ๋  ํ•„์š”๊ฐ€ ์—†๋Š” ์ •๋ณด๋Š” ์ˆจ๊ธฐ๋Š” ๊ฒƒ์„ ๋งํ•˜๋ฉฐ ๋‹ค๋ฅธ ๋ง๋กœ ์ •๋ณด ์€๋‹‰(information hiding)์ด๋ผ๊ณ  ํ•œ๋‹ค.

var Person = function(arg) {
  var name = arg ? arg : ''; // โ‘ 

  this.getName = function() {
    return name;
  };

  this.setName = function(arg) {
    name = arg;
  };
}

var me = new Person('Lee');

var name = me.getName();

console.log(name);

me.setName('Kim');
name = me.getName();

console.log(name);

โ‘ ์˜ name ๋ณ€์ˆ˜๋Š” private ๋ณ€์ˆ˜๊ฐ€ ๋œ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” function-level scope๋ฅผ ์ œ๊ณตํ•˜๋ฏ€๋กœ ํ•จ์ˆ˜ ๋‚ด์˜ ๋ณ€์ˆ˜๋Š” ์™ธ๋ถ€์—์„œ ์ฐธ์กฐํ•  ์ˆ˜ ์—†๋‹ค. ๋งŒ์•ฝ์— var ๋•Œ์‹  this๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด public ๋ฉค๋ฒ„๊ฐ€ ๋œ๋‹ค. ๋‹จ new ํ‚ค์›Œ๋“œ๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š์œผ๋ฉด this๋Š” ์ƒ์„ฑ๋œ ๊ฐ์ฒด์— ๋ฐ”์ธ๋”ฉ๋˜์ง€ ์•Š๊ณ  ์ „์—ญ๊ฐ์ฒด์— ์—ฐ๊ฒฐ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  public ๋ฉ”์†Œ๋“œ getName, setName์€ ํด๋กœ์ €๋กœ์„œ private ๋ณ€์ˆ˜(์ž์œ  ๋ณ€์ˆ˜)์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๊ฒƒ์ด ๊ธฐ๋ณธ์ ์ธ ์ •๋ณด ์€๋‹‰ ๋ฐฉ๋ฒ•์ด๋‹ค.

 

7-2) ์ถ”์ƒํ™”(Abstraction)
์ถ”์ƒํ™”๋Š” ์ž‘์—… ๋ฌธ์ œ์˜ ํ˜„์žฌ ๋ถ€๋ถ„์„ ๋ชจ๋ธ๋งํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๋งค์ปค๋‹ˆ์ฆ˜์ด๋‹ค. ์ถ”์ƒํ™”๋Š” ์ƒ์†(specialization, ์ถ”์ƒ์˜ ์ˆ˜์ค€์„ ๋‚ฎ์ถ”๋Š” ๊ฒƒ)๊ณผ ํ•ฉ์„ฑ์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์ƒ์†์— ์˜ํ•ด ํŠน๋ณ„ํ™”(specialization)๋ฅผ, ํด๋ž˜์Šค๋“ค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋‹ค๋ฅธ ๊ฐ์ฒด์˜ ์†์„ฑ๊ฐ’์ด ๋˜๊ฒŒ ํ•จ์œผ๋กœ์จ ํ•ฉ์„ฑ์„ ๊ตฌํ˜„ํ•œ๋‹ค.

  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Function ํด๋ž˜์Šค๋Š” Object ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๊ณ (์ด๋Š” ๋ชจ๋ธ์˜ ํŠน๋ณ„ํ™”๋ฅผ ๋ณด์—ฌ์ค€๋‹ค),
  • Function.prototype ์†์„ฑ์€ Object์˜ ์ธ์Šคํ„ด์Šค์ด๋‹ค(์ด๋Š” ํ•ฉ์„ฑ์„ ๋ณด์—ฌ์ค€๋‹ค).

 

7-3) ๋‹คํ˜•์„ฑ(Polymorphism)
๋ชจ๋“  ๋ฉ”์„œ๋“œ์™€ ์†์„ฑ๋“ค์€ prototype ์†์„ฑ์— ์„ ์–ธ๋˜์–ด ์žˆ๊ณ , ํด๋ž˜์Šค๊ฐ€ ๋‹ค๋ฅด๋‹ค๋ฉด ๊ฐ™์€ ์ด๋ฆ„์˜ ๋ฉ”์„œ๋“œ๋„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฉ”์„œ๋“œ๋“ค์€ ๋ฉ”์„œ๋“œ๊ฐ€ ์„ ์–ธ๋œ ํด๋ž˜์Šค๋กœ ๊ทธ ์‹คํ–‰ ์˜์—ญ์ด ํ•œ์ •๋œ๋‹ค. ๋ฌผ๋ก  ์ด๊ฑด ๋‘ ๊ฐœ์˜ ํด๋ž˜์Šค๋“ค์ด ์„œ๋กœ ๋ถ€๋ชจ-์ž์‹ ๊ด€๊ณ„๊ฐ€ ์•„๋‹๋•Œ์—๋งŒ ์„ฑ๋ฆฝํ•œ๋‹ค. ์ฆ‰ ๋‹ค์‹œ ๋งํ•ด ๋ถ€๋ชจ-์ž์‹ ๊ด€๊ณ„์˜ ์ƒ์† ๊ด€๊ณ„๋กœ ํ•˜๋‚˜๊ฐ€ ๋‹ค๋ฅธ ํ•˜๋‚˜์—๊ฒŒ์„œ ์ƒ์†๋ฐ›์ง€ ์•Š์•˜์„ ๋•Œ์—๋งŒ ์„ฑ๋ฆฝํ•œ๋‹ค.