๐Ÿชด ์„ฑ์žฅ์ผ์ง€

์ฑ… ํ–‰๋ณตํ•œ ์ด๊ธฐ์ฃผ์˜์ž(์›จ์ธ ๋‹ค์ด์–ด)์˜ ๋‚ด์šฉ์— ์ž๊ทน๋ฐ›์•„ ์‹œ์ž‘ํ•˜๋Š” ์†Œ๋ฐ•ํ•œ ์„ฑ์žฅ๊ธฐ๋ก

์‚ด์•„์žˆ๋Š” ๊ฝƒ๊ณผ ์ฃฝ์€ ๊ฝƒ์€ ์–ด๋–ป๊ฒŒ ๊ตฌ๋ณ„ํ•˜๋Š”๊ฐ€?
์„ฑ์žฅํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด ์‚ด์•„ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.
์ƒ๋ช…์˜ ์œ ์ผํ•œ ์ฆ๊ฑฐ๋Š” ์„ฑ์žฅ์ด๋‹ค!

๐ŸŒณ ํ‚ค์›Œ๋“œ ์ตœ๋Œ€ํ•œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ •๋ฆฌ, ์ถ”ํ›„์— ๋ณด๋ฉด์„œ ์Šค์Šค๋กœ ์„ค๋ช…

JavaScript ํ”„๋กœํ† ํƒ€์ž…(remind)

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ธฐ๋ฐ˜์ด ๋˜๋Š” ๊ฐœ๋…์œผ๋กœ ์–ด๋–ค ์ƒ์„ฑ์ž ํ•จ์ˆ˜์˜ ๋ฉ”์„œ๋“œ๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ํŠน๋ณ„ํ•œ ๊ฐ์ฒด
์ด ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด instance๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋˜๋ฉด instance๋Š” __proto__๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ์ž์˜ prototype ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ๊ทธ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ

์‚ฌ์‹ค instance.__proto__๋ณด๋‹ค Object.getPrototypeOf(instance)๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์„ ๊ถŒ์žฅ

__proto__๋Š” ์ƒ๋žต ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ -> ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์–ธ์–ด๋ฅผ ์ฐฝ์‹œํ•œ ๋ธŒ๋žœ๋“  ์•„์ดํฌ๊ฐ€ ์ •ํ•œ ๊ฒƒ์œผ๋กœ ์ดํ•ด์˜ ์˜์—ญ์ด ์•„๋‹˜! ๊ทธ๋ƒฅ ๊ทธ๋ ‡๊ตฌ๋‚˜ ํ•˜๋ฉด ๋จ

var instance = new Constructor();
// ์•„๋ž˜ 5๊ฐ€์ง€ ๋ชจ๋‘ ๊ฐ™์€ Constructor๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํ‘œํ˜„
Constructor;
instance.__proto__.constructor;
instance.constructor; // __proto__ ์ƒ๋žต ๊ฐ€๋Šฅ
Object.getPrototype(instance).comstructor;
Constructor.prototype.constructor;

๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋“œ

  • ์Šค์ฝ”ํ”„ ์ฒด์ด๋‹๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ๊ฐ™์€ ์ด๋ฆ„์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์—ฌ๋Ÿฌ ๊ณณ์— ์žˆ์„ ๋•Œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๊ณณ์—์„œ ๊ทธ ๋ฉ”์„œ๋“œ์— ์ ‘๊ทผ
var Dog = function (name) {
  this.name = name;
};

Dog.prototype.bark = function () {
  return this.name + ' ์™ˆ์™ˆ~!';
};

var hodu = new Dog('hodu');
hodu.bark = function () {
  return this.name + ' ๋ฐ”์šฐ๋ฐ”์šฐ~!';
};

console.log(hodu.bark()); // hodu ๋ฐ”์šฐ๋ฐ”์šฐ~! -> ์ฆ‰, protorype์˜ ๋ฉ”์„œ๋“œ๋ณด๋‹ค instance์˜ ์ž์ฒด ๋ฉ”์„œ๋“œ๊ฐ€ ๋” ์šฐ์„ 
console.log(hodu.__proto__.bark()); // undefined -> this๊ฐ€ hodu๊ฐ€ ์•„๋‹Œ hodu__proto__๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ๋จ
console.log(hodu.__proto__.bark.call(hodu)); // hodu ์™ˆ์™ˆ~! -> call์„ ํ†ตํ•ด this๋ฅผ hodu๋กœ ๋ฐ”์ธ๋”ฉํ•ด์ฃผ๋ฉด ํ•ด๊ฒฐ

Object

  • ๋ชจ๋“  ์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์˜ํ•ด ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋“ค์€ prototype์ด๋ผ๋Š” ํ”„๋กœํผํ‹ฐ ์ž์ฒด๊ฐ€ โ€˜Objectโ€™์ด๋ฏ€๋กœ Object์˜ prototype์— ์žˆ๋Š” ๋ชจ๋“  ๋ฉ”์„œ๋“œ์— ์ ‘๊ทผ ๊ฐ€๋Šฅ
  • ๋‹จ, ์ •๋ง ๊ฐ์ฒด({})๋งŒ์ด ๊ฐ€์ง„ ํ•จ์ˆ˜๋„ ํ•„์š”ํ•˜๋ฏ€๋กœ ๊ทธ ๋ถ€๋ถ„์€ static method๋กœ Object.freeze์™€ ๊ฐ™์€ ํ˜•์‹์œผ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

๋‹ค์ค‘ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ

์ƒ์„ฑ์ž์˜ prototype์— ๋˜๋‹ค๋ฅธ ์ƒ์„ฑ์ž์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ํ• ๋‹นํ•จ์œผ๋กœ์จ ๊ทธ ์ƒ์„ฑ์ž์˜ ๋ฉ”์„œ๋“œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๊ณ„์† ์ฒด์ธํ•˜๋Š” ๋ฐฉ๋ฒ•

  • ์ด ๊ฐœ๋… ์ž์ฒด๊ฐ€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ ์‹œ ์‚ฌ์šฉ๋จ

JavaScript ํด๋ž˜์Šค(remind)

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ํ”„๋กœํ† ํƒ€์ž… ๊ธฐ๋ฐ˜์ด๊ธฐ์— ์ƒ์†์ด๋ผ๋Š” ๊ฐœ๋…์ด ์กด์žฌํ•˜์ง€ ์•Š์Œ
์ด๋ ‡๋“ฏ ์ƒ์†์˜ ๊ฐœ๋…์ด ์กด์žฌํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ๋”ฐ๋ผํ•˜๊ธฐ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ๊ธฐ๋ฒ•๋“ค์ด ์ƒ๊ฒผ์Œ
์ถ”ํ›„ ES6์—์„œ๋Š” ํด๋ž˜์Šค ๋ฌธ๋ฒ•์ด ๊ตฌํ˜„๋˜์—ˆ์Œ(์ด๋งˆ์ €๋„ ํ”„๋กœํ† ํƒ€์ž…์€ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ๊ฒƒ)

  • superclass: ์ƒ์œ„ ํด๋ž˜์Šค; super
  • subclass: ํ•˜์œ„ ํด๋ž˜์Šค; sub

ํ˜„์‹ค ์„ธ๊ณ„๋Š” ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์ˆ˜๋งŽ์€ ๊ฐœ์ฒด๋“ค์˜ ๊ณตํ†ต์ , ์ฐจ์ด์ ์„ ๋ถ„์„ํ•˜์—ฌ ํด๋ž˜์Šค๋ฅผ ํ•˜๋‚˜ํ•˜๋‚˜ ์ •์˜ํ•˜๋Š” ์‹
ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„  ํŠน์ • ํด๋ž˜์Šค๋ฅผ ๋จผ์ € ๋งŒ๋“  ํ›„, ๊ทธ ํด๋ž˜์Šค์˜ ์„ฑ์งˆ๊ณผ ๊ฐ๊ฐ์ด ๊ฐ–๋Š” ๊ฐœ๋ณ„ ์„ฑ์งˆ์„ ๊ฐ–๋Š” ๊ฐœ์ฒด๋ฅผ ๋งŒ๋“ค์–ด๋‚ด๊ฒŒ ๋จ

  • static method: ์ƒ์„ฑ์ž ์ž์ฒด๊ฐ€ ๊ฐ–๋Š” ๋ฉ”์„œ๋“œ(ํ•จ์ˆ˜) ex) Array.from() -> instance๊ฐ€ ํ™œ์šฉ ๋ถˆ๊ฐ€๋Šฅ
  • prototype method: ์ƒ์„ฑ์ž์˜ prototype์ด ๊ฐ–๋Š” ๋ฉ”์„œ๋“œ(ํ•จ์ˆ˜) ex) Array.prototype.push() -> instance๊ฐ€ ํ™œ์šฉ ๊ฐ€๋Šฅ
  • instance method: instance๊ฐ€ ๊ฐ–๋Š” ๋ฉ”์„œ๋“œ(ํ•จ์ˆ˜)๋กœ instance๋งˆ๋‹ค ์ง์ ‘ ๋ถ€์—ฌํ•˜๋Š” ๋ฉ”์„œ๋“œ ํ•จ์ˆ˜

ํด๋ž˜์Šค ์ƒ์†: ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ํด๋ž˜์Šค ์ƒ์†์„ ๊ตฌํ˜„ -> ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ด๋‹์„ ์ž˜ ์—ฐ๊ฒฐํ–ˆ๋‹ค๋Š” ์˜๋ฏธ

var First = function (name) {
  this.name = name;
};

First.prototype = []; // ํ”„๋กœํ† ํƒ€์ž…์— Array์˜ instance(๋ฐฐ์—ด ๋ฆฌํ„ฐ๋Ÿด ํ‘œํ˜„)์„ ํ• ๋‹น

var jayden = new First('jayden');
jayden.push(); // ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ด๋‹์— ์˜ํ•ด Array์˜ prototype method๋ฅผ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ด์ง

์œ„์˜ ๊ฒฝ์šฐ 2๊ฐ€์ง€์˜ ๋ฌธ์ œ๊ฐ€ ์กด์žฌ

  1. First.prototype์— []๋ฅผ ํ• ๋‹นํ•จ์œผ๋กœ์จ [] ์ž์ฒด๊ฐ€ ๊ฐ–๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์˜ค๋ฅ˜๋ฅผ ์ผ์œผํ‚ฌ ๊ฐ€๋Šฅ์„ฑ์ด ์กด์žฌ
  2. jayden์˜ ์ƒ์„ฑ์ž์ธ First์— ๋‹ค์‹œ ์ ‘๊ทผํ•  ๋ฐฉ๋ฒ•์ด ์—†์Œ(First.prototype = []์œผ๋กœ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ)

1๋ฒˆ ๋ฌธ์ œ ํ•ด๊ฒฐ๋ฒ•

  • delete First.prototype.method ์‹์œผ๋กœ ํ•˜๋‚˜ํ•˜๋‚˜ ์ง€์›Œ์ฃผ๊ธฐ
  • ๋น„์–ด์žˆ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜ Bridge๋ฅผ ํ†ตํ•ด ์—ฐ๊ฒฐ
  • Object.create(์ƒ์„ฑ์ž.prototype)์„ ์‚ฌ์šฉํ•ด์„œ ์—ฐ๊ฒฐ

2๋ฒˆ ๋ฌธ์ œ ํ•ด๊ฒฐ๋ฒ•

Subclass.prototype.constructor = Subclass ๋กœ ๋‹ค์‹œ constructor๋ผ๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์žฌํ• ๋‹น

ES6์— ์ถ”๊ฐ€๋œ ํด๋ž˜์Šค ๋ฌธ๋ฒ• ์˜ˆ์‹œ

var ES6 = class {
  constructor(name) {
    this.name = name;
  }
  static staticMethod() {
    return this.name + ' staticMethod';
  }
  method() {
    return this.name + ' method';
  }
};

var es6Instance = new ES6('es6');