Use Constructor Functions - Lee-hyuna/33-js-concepts-kr GitHub Wiki

Use Constructor Functions

์ง€๋‚œ ์ฑ•ํ„ฐ์—์„œ ์šฐ๋ฆฌ๋Š” object prototypes๊ณผ Object.create ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ ํ•œ ํ›„์—๋Š” init์ด๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ–ˆ๋‹ค. ์ด initํ•จ์ˆ˜๋Š” ์ข…์ข… ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ "set up"ํ•˜๊ธฐ ์œ„ํ•ด ์‹คํ–‰ํ•˜๊ธฐ๋ฅผ ์›ํ•˜๋ฉฐ, ๋Œ€๋ถ€๋ถ„์˜ ๊ฐ์ฒด ์ง€ํ–ฅ ์–ธ์–ด๋Š” ์ดinit ํ•จ์ˆ˜์˜ ๊ฐœ๋…์„ ์ง์ ‘ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. Javascript์—์„œ, ๋‚ด์žฅ๋œ initํ•จ์ˆ˜๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ผ๊ณ  ๋ถˆ๋ฆฌ๋ฉฐ, ํŠน๋ณ„ํ•œ Javascript ํ‚ค์›Œ๋“œnew๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋ฉด ๊ฐ์ฒด์— ๋Œ€ํ•ด ์›ํ•˜๋Š” init๊ธฐ๋Šฅ์„ ํฌํ•จํ•˜๋Š” ๋…๋ฆฝํ˜• ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜๋ฉด๋ฉ๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋ฅผ init๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๋Œ€์‹ ์—, ์ด ํ•จ์ˆ˜๋Š” ์šฐ๋ฆฌ ๊ฐ์ฒด์˜ class์ด๋ฆ„์„ ๊ฐ€์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง€๋‚œ ์ฑ•ํ„ฐ์˜ pastry code๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•œ ๊ฒฝ์šฐ์˜ ๋ชจ์Šต์ž…๋‹ˆ๋‹ค.

var Pastry = {
  // initialize the pastry
  init: function (type, flavor, levels, price, occasion) {
    this.type = type;
    this.flavor = flavor;
    this.levels = levels;
    this.price = price;
    this.occasion = occasion;
  },
  ...
}

์ด๋ ‡๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

function Pastry(type, flavor, levels, price, occasion) {
  this.type = type;
  this.flavor = flavor;
  this.levels = levels;
  this.price = price;
  this.occasion = occasion;
}

์ด์ œ ์ธ์Šคํ„ด์Šคํ™”ํ•˜๋ ค๋ฉด ํ˜ธ์ถœํ•˜๋Š” ๋Œ€์‹ 

Object.create(Pastry);

๊ทธ๋Ÿฐ ๋‹ค์Œ init ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค

new Pastry(type, flavor, levels, price, occasion);

๊ทธ๋ ‡์ง€๋งŒ Pastry๊ฐ์ฒด์— ์˜ํ•ด ์ •์˜ ๋œ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ? ์šฐ๋ฆฌ์˜ Pastry์—๋Š” describeํ•จ์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

var Pastry = {
  // initialize the pastry
  init: function (type, flavor, levels, price, occasion) {
    this.type = type;
    this.flavor = flavor;
    this.levels = levels;
    this.price = price;
    this.occasion = occasion;
  },

  // Describe the pastry
  describe: function () {
    var description = "The " + this.type + " is a " + this.occasion + " pastry, has a " + this.flavor + " flavor, " + this.levels + " layer(s), and costs " + this.price + ".";
    return description;
  }
};

์ด๊ฒƒ์€ Prototype์ด ๋‹ค์‹œ ๋“ค์–ด์˜ค๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค.

์ง€๋‚œ ์ฑ•ํ„ฐ์ธ Pastry๊ฐ์ฒด๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ๋ชจ๋“  Pastry์˜ prototype ์—ญํ• ์„ ํ–ˆ์Œ์„ ๊ธฐ์–ตํ•˜์‹ญ์‹œ์˜ค. Pastry object์—์„œ ์ •์˜ํ•œ init, describe์™€ ๊ฐ™์€ ๋ชจ๋“  ํ•จ์ˆ˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ƒ์„ฑ ํ•  ๋•ŒPastry๋ฅผObject.create์— ์ „๋‹ฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ๊ฐ€ ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์•ฝ๊ฐ„ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋‹จ์ˆœํžˆ Pastry์ƒ์„ฑ์ž ํ•จ์ˆ˜์— ์†์„ฑ์„ ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์—†์œผ๋ฉฐ ์ƒ์„ฑ์ž๊ฐ€ ์ƒ์„ฑ ํ•œ ๊ฐ์ฒด์˜ prototype๊ณผ ๋™์ผํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— class์˜ ์ธ์Šคํ„ด์Šคํ™”๋ฅผ ๊ธฐ๋Œ€ํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

๋‹คํ–‰ํžˆ๋„, ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋Š” ์ƒ์„ฑํ•œ ๊ฐ์ฒด์˜ prototype์— ๋Œ€ํ•œ ํŠน๋ณ„ํ•œ ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, ์ง€๋‚œ ์ฑ•ํ„ฐ์—์„œ prototype๊ณผ ๊ฐ™์ด ์ƒ์† ๊ฐ€๋Šฅํ•œ ์†์„ฑ์„ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์šฐ๋ฆฌ๋Š” describeํ•จ์ˆ˜๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด Pastry prototype์— ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.

function Pastry(type, flavor, levels, price, occasion) {
  this.type = type;
  this.flavor = flavor;
  this.levels = levels;
  this.price = price;
  this.occasion = occasion;
}

Pastry.prototype.describe = function () {
  var description = "The " + this.type + " is a " + this.occasion + "pastry, has a " + this.flavor + " flavor, " + this.levels + " layer(s), and costs " + this.price + ".";
  return description;
}

์ง€๋‚œ ์ฑ•ํ„ฐ์—์„œ, ์šฐ๋ฆฌ๋Š” ๋ชจ๋“  ์ƒˆ๋กœ์šด ๊ฐ์ฒด ์ƒ์„ฑ์„ ๋‘ ์ค„๋กœ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

var muffin = Object.create(Pastry);
muffin.init("muffin", "blueberry", 1, "$2", "breakfast");

var cake = Object.create(Pastry);
cake.init("cake", "vanilla", 3, "$10", "birthday");

console.log(muffin.describe());
console.log(cake.describe());

์ด์ œ, ๊ฐ์ฒด ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์„œ, ์šฐ๋ฆฌ๋Š” ํ•œ ์ค„๋กœ ์šฐ๋ฆฌ ๊ฐ์ฒด๋ฅผ ์ธ์Šคํ„ด์Šคํ™” ํ•˜์—ฌ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ–๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

var muffin = new Pastry("muffin", "blueberry", 1, "$2", "breakfast");
var cake = new Pastry("cake", "vanilla", 3, "$10", "birthday");

console.log(muffin.describe());
console.log(cake.describe());
์ƒ์„ฑ์žํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ ํ•  ๋•Œ๋Š” 'new'๋ฅผ ์žŠ์–ด๋ฒ„๋ฆฌ์ง€ ๋งˆ์„ธ์š”!

์ƒ์„ฑ์žํ•จ์ˆ˜์™€ ๊ด€๋ จํ•˜์—ฌ ์ค‘์š”ํ•œ ํฌ์ธํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
pastry๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•˜๋ฉฐ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ์„œ Pastryํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋Œ€์‹ ์— , newํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๊นŒ๋จน์„ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ์ƒ์„ฑ์žํ•จ์ˆ˜๋Š” return๋ฌธ์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ๋”๋ผ๋„ ๋ง์ž…๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜ ๊ฐ’์„ ์ง€์ •ํ•˜์ง€ ์•Š๋Š” ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ๊ฐ’์€ "undefined"์ด๋ฏ€๋กœ, ํŠน๋ณ„ํ•œ newํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๊ฐ–๊ฒŒ ๋˜๋Š” ๊ฐ’์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‹น์‹ ์ด๋‚˜ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๊ฐ€ ๋‹น์‹ ์˜ ๊ฐ์ฒด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฒ„๊ทธ๋กœ ์ด์–ด์ง€๋Š” ๊ฒƒ์„ ํ”ํ•˜๊ฒŒ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// gonna instantiate some sweet beignets...
var beignet = Pastry("beignet", "cream", 1, "$1.50", "anytime you want beignets");

console.log(beignet.describe());
> Uncaught TypeError: Cannot read property 'describe' of undefined

์ด๊ฒƒ์€ ๊ฑฐ์˜ ํ™•์‹คํžˆ ๋‹น์‹ ์˜ ํ•จ์ˆ˜๊ฐ€ ์‹คํŒจํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ์— ๋‹น์‹ ์—๊ฒŒ ํ–‰์šด์ด ์žˆ๋‹ค๋ฉด์š”!

๋” ๋‚˜์˜๊ณ  ๋””๋ฒ„๊น…ํ•˜๊ธฐ ์–ด๋ ค์šด ์—ฌ๊ธฐ์„œ์˜ ์œ„ํ—˜์€ ๋‹น์‹ ์ด callbeignet.describe()๋ฅผ ํ˜ธ์ถœํ• ๋•Œ๊ฐ€ ์•„๋‹Œ, ๋‹น์‹ ์ด newํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๊ฐ์ฒด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ• ๋•Œ ๋ฌด์–ธ๊ฐ€ ์กฐ์šฉํžˆ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋‹น์‹ ์ด newํ‚ค์›Œ๋“œ ์—†์ด Pastryํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•œ ํ›„์— window.type์˜ ๊ฐ’์„ ํ™•์ธํ•ด๋ณด์„ธ์š”.

var beignet = Pastry("beignet", "cream", 1, "$1.50", "anytime you want beignets");
window.type
> beignet

๋‹น์‹ ์€ ์•„๋งˆ๋„ window๊ฐ์ฒด๊ฐ€ ์ต์ˆ™ํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. (์šฐ๋ฆฌ๋Š” ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ ์ข€ ๋” ๋ฐฐ์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค) ํ•˜์ง€๋งŒ, ์ด๊ฒƒ์€ ๋‹น์‹ ์˜ ๋ชจ๋“  ์›นํŽ˜์ด์ง€์˜ ๊ธฐ์ดˆ์™€ ๊ทผ๋ณธ์ด๊ณ  ๋ฌด์˜์‹์ ์œผ๋กœ ํ”„๋กœํผํ‹ฐ๋“ค์„ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์€ ๋‹น์‹ ์˜ ํ”„๋กœ๊ทธ๋žจ์— ๊ต‰์žฅํžˆ ์œ„ํ—˜ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
ํŠนํžˆ ๋‹น์‹ ์ด ์šฐ์—ฐํžˆ๋„ ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ฎ์–ด์“ด๋‹ค๋ฉด ๋ง์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ๋‹ค์Œ ์ฑ•ํ„ฐ์—์„œ ์Šค์ฝ”ํ”„ ๊ฐœ๋…์„ ๋ฐฐ์šฐ๊ณ  ์ „์—ญ ๊ฐ์ฒด๋ฅผ ๋ฐฐ์šธ๋•Œ ์–ด๋–ป๊ฒŒ ์ด๊ฒƒ์ด ๋ฐœ์ƒํ•˜๋Š”์ง€ ์šฐ๋ฆฌ๋Š” ์ข€ ๋” ์ด์•ผ๊ธฐ ๋‚˜๋ˆŒ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ง€๊ธˆ์€ ๋‹น์‹ ์ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ์žํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ดˆ๊ธฐํ™”ํ• ๋•Œ newํ‚ค์›Œ๋“œ๋ฅผ ์ƒ๋žตํ• ์ˆ˜๋„ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•˜์„ธ์š”.