πŸ“ 였늘 ν•œ 것

  1. 클래슀

πŸ“š 배운 것

7. 클래슀

1) ν΄λž˜μŠ€μ™€ μΈμŠ€ν„΄μŠ€μ˜ κ°œλ… 이해

ν΄λž˜μŠ€λŠ” 곡톡 μš”μ†Œλ₯Ό μ§€λ‹ˆλŠ” 집단을 λΆ„λ₯˜ν•˜κΈ° μœ„ν•œ κ°œλ…μ΄λ‹€.
ES5κΉŒμ§€μ˜ μžλ°”μŠ€ν¬λ¦½νŠΈμ—λŠ” ν΄λž˜μŠ€κ°€ μ—†κ³ , ES6μ—μ„œ ν΄λž˜μŠ€κ°€ λ„μž…λ˜μ—ˆλ‹€.
ν΄λž˜μŠ€λŠ” ν•˜μœ„λ‘œ 갈수둝 μƒμœ„ 클래슀의 속성을 μƒμ†ν•˜λ©΄μ„œ 더 ꡬ체적인 μš”κ±΄μ΄ μΆ”κ°€ λ˜λŠ” λ³€κ²½λœλ‹€. (μƒμœ„ 클래슀 / ν•˜μœ„ 클래슀)
ν•œνŽΈ, μΈμŠ€ν„΄μŠ€λž€ μ–΄λ–€ 클래슀의 속성을 μ§€λ‹ˆλŠ” μ‹€μ‘΄ν•˜λŠ” 개체λ₯Ό λ§ν•œλ‹€.
ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ—μ„œλŠ” ν΄λž˜μŠ€κ°€ λ¨Όμ € μ •μ˜λ˜μ–΄μ•Όλ§Œ κ·Έλ‘œλΆ€ν„° 곡톡적인 μš”μ†Œλ₯Ό μ§€λ‹ˆλŠ” 개체(μΈμŠ€ν„΄μŠ€)듀을 생성할 수 μžˆλ‹€.

2) μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 클래슀

var Rectangle = function (name) {
  this.width = width;
  this.height = height;
};

Rectangle.prototype.getArea = function () {
  return this.width * this.height;
};

Rectangle.isRectangle = function (instance) {
  return instance instanceOf Rectangle && instance.width > 0 && instance.height > 0;
};

var rect1 = new Rectangle(3, 4);
console.log(rect1.getArea()); // 12
console.log(rect1.isRectangle(rect1)); // Uncaught TypeError: not a function
console.log(Rectangle.isRectangle(rect1)); // true

ν”„λ‘œν† νƒ€μž… λ©”μ„œλ“œλŠ” 클래슀의 prototype 내뢀에 μ •μ˜λœ λ©”μ„œλ“œλ‘œμ„œ μΈμŠ€ν„΄μŠ€κ°€ 마치 μžμ‹ μ˜ κ²ƒμ²˜λŸΌ ν˜ΈμΆœν•  수 μžˆλ‹€.
μŠ€νƒœν‹± λ©”μ„œλ“œλŠ” 클래슀(μƒμ„±μž ν•¨μˆ˜)에 직접 μ •μ˜ν•œ λ©”μ„œλ“œλ‘œμ„œ μΈμŠ€ν„΄μŠ€κ°€ 직접 ν˜ΈμΆœν•  수 μ—†κ³  클래슀(μƒμ„±μž ν•¨μˆ˜)에 μ˜ν•΄μ„œλ§Œ ν˜ΈμΆœν•  수 μžˆλ‹€.

ꡬ체적인 μΈμŠ€ν„΄μŠ€κ°€ μ‚¬μš©ν•  λ©”μ„œλ“œλ₯Ό μ •μ˜ν•œ 'ν‹€'의 역할을 ν•  λ•Œμ˜ ν΄λž˜μŠ€λŠ” 좔상적인 κ°œλ…μ΄λ‹€.
κ·ΈλŸ¬λ‚˜, μŠ€νƒœν‹± λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  λ•Œμ˜ ν΄λž˜μŠ€λŠ” 클래슀(μƒμ„±μž ν•¨μˆ˜) μžμ²΄κ°€ thisκ°€ λ˜μ–΄ λ©”μ„œλ“œμ— 직접 μ ‘κ·Όν•˜λ―€λ‘œ ν•˜λ‚˜μ˜ ꡬ체적인 κ°œμ²΄λ‘œμ„œ μ·¨κΈ‰λœλ‹€.

3) 클래슀 상속

(1) κΈ°λ³Έ κ΅¬ν˜„

닀쀑 ν”„λ‘œν† νƒ€μž… 체인을 μ΄μš©ν•΄ 클래슀 상속을 κ΅¬ν˜„ν•  수 μžˆλ‹€.
μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ 클래슀 상속을 κ΅¬ν˜„ν–ˆλ‹€λŠ” 것은 곧 ν”„λ‘œν† νƒ€μž… 체이닝을 잘 μ—°κ²°ν–ˆλ‹€λŠ” λœ»μ΄λ‹€.
μ•žμ„œ μ°Έκ³ ν–ˆλ˜ 예제λ₯Ό λ‹€μ‹œ κ°€μ Έμ™”λ‹€.

예제 1: Array λ‚΄μž₯ 클래슀λ₯Ό μƒμ†ν•˜λŠ” ν•˜μœ„ 클래슀

var Grade = function () {
  var args = Array.prototype.slice.call(arguments);
  for (var i = 0; i < args.length; i++) {
    this[i] = args[i];
  }
  this.length = args.length;
};

Grade.prototype = [];
var g = new Grade(100, 80);
console.log(g); // // Grade { 0: 100, 1: 80, length: 2 }

delete g.length; // gμ—μ„œ length ν”„λ‘œνΌν‹°κ°€ μ‚­μ œλœλ‹€
g.push(70); // g의 length κ°’μœΌλ‘œ g.__proto__.length(즉, Grade.prototype.length)의 κ°’(0)을 μ½μ–΄μ˜¨ ν›„ g에 70을 push ν•œλ‹€
console.log(g); // Grade { 0: 70, 1: 80, length: 1 }

κ·ΈλŸ¬λ‚˜ μœ„ 예제 μ½”λ“œμ—λŠ” λͺ‡ 가지 큰 λ¬Έμ œκ°€ μžˆλ‹€.

  • length ν”„λ‘œνΌν‹°κ°€ configurable(μ‚­μ œ κ°€λŠ₯)ν•˜λ‹€.
  • Grade.prototype에 빈 배열을 μ°Έμ‘°μ‹œμΌ°λ‹€. ( = ν•˜μœ„ ν΄λž˜μŠ€κ°€ ꡬ체적인 데이터λ₯Ό 가진닀.)

λ‚΄μž₯ 객체인 λ°°μ—΄ μΈμŠ€ν„΄μŠ€μ˜ length ν”„λ‘œνΌν‹°λŠ” μ‚­μ œκ°€ λΆˆκ°€λŠ₯ν•œ 반면, Grade 클래슀의 μΈμŠ€ν„΄μŠ€λŠ” Grade.prototype = []에 μ˜ν•΄ λ°°μ—΄ λ©”μ„œλ“œλ₯Ό μƒμ†ν•˜λ©΄μ„œλ„, κΈ°λ³Έμ μœΌλ‘œλŠ” 일반 객체의 μ„±μ§ˆμ„ κ·ΈλŒ€λ‘œ μ§€λ‹ˆλ―€λ‘œ length ν”„λ‘œνΌν‹°λ₯Ό μ‚­μ œν•  수 μžˆλ‹€.

이와 같은 였λ₯˜λ₯Ό μ ‘ν•˜μ§€ μ•ŠκΈ° μœ„ν•΄μ„œλŠ” ν΄λž˜μŠ€μ— μžˆλŠ” 값이 μΈμŠ€ν„΄μŠ€μ˜ λ™μž‘μ— 영ν–₯을 주지 μ•Šκ²Œλ” ν΄λž˜μŠ€κ°€ ꡬ체적인 데이터λ₯Ό μ§€λ‹ˆμ§€ μ•Šλ„λ‘ ν•΄μ•Ό ν•œλ‹€.

예제 2: μ‚¬μš©μžκ°€ μ •μ˜ν•œ 두 클래슀 μ‚¬μ΄μ˜ 상속 관계

// μ§μ‚¬κ°ν˜• 클래슀 & μ •μ‚¬κ°ν˜• 클래슀
var Rectangle = function (width, height) {
  this.width = width;
  this.height = height;
};

Rectangle.prototype.getArea = function () {
  return this.width * this.height;
};

var rect = new Rectangle(3, 4);
console.log(rect.getArea()); // 12

var Square = function (width) {
  Rectangle.call(this, width, width);
};

Square.prototype = new Rectangle(); // ν•˜μœ„ 클래슀의 prototype에 μ—°κ²°ν•˜κ³ μž ν•˜λŠ” μƒμœ„ 클래슀(μƒμ„±μž ν•¨μˆ˜)의 μΈμŠ€ν„΄μŠ€ ν• λ‹Ή

var sq = new Square(5);
console.log(sq.getArea()); // 25

console.dir(sq)을 μ‹€ν–‰ν•΄ sq μΈμŠ€ν„΄μŠ€λ₯Ό μ‚΄νŽ΄λ³΄λ©΄ ν΄λž˜μŠ€κ°€ ꡬ체적인 데이터λ₯Ό 가지고 μžˆμŒμ„ 확인할 수 μžˆλ‹€.

Square
  height: 5
  width: 5
  __proto__: Rectangle // ν΄λž˜μŠ€κ°€
    height: undefined // undefined λΌλŠ” 값을 가진닀
    width: undefined // undefined λΌλŠ” 값을 가진닀
    __proto__ :
      getArea: f ()
      constructor: f (width, height)
      __proto__: Object

λ˜ν•œ, sq μΈμŠ€ν„΄μŠ€μ˜ constructorκ°€ Squareκ°€ μ•„λ‹ˆλΌ Rectangle을 μ°Έμ‘°ν•œλ‹€λŠ” λ¬Έμ œμ μ„ 가진닀.

var rect2 = sq.constructor(2, 3);
console.log(rect2); // Rectangle { width: 2, height: 3 }

μ •λ¦¬ν•˜μžλ©΄, ν•˜μœ„ 클래슀둜 삼을 μƒμ„±μž ν•¨μˆ˜μ˜ prototype에 μƒμœ„ 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό λΆ€μ—¬ν•¨μœΌλ‘œμ¨(닀쀑 ν”„λ‘œν† νƒ€μž… 체인) 기본적인 λ©”μ„œλ“œ 상속은 κ°€λŠ₯ν•˜μ§€λ§Œ λ‹€μ–‘ν•œ λ¬Έμ œκ°€ λ°œμƒν•  여지가 μžˆλ‹€κ³  ν•  수 μžˆλ‹€.

(2) ν΄λž˜μŠ€κ°€ ꡬ체적인 데이터λ₯Ό μ§€λ‹ˆμ§€ μ•Šκ²Œ ν•˜λŠ” 방법

클래슀 상속 및 좔상화λ₯Ό μœ„ν•΄μ„œλŠ” SubClass.prototype.__proto__κ°€ SuperClass.prototype을 μ°Έμ‘°ν•˜κ³ , SubClass.prototypeμ—λŠ” λΆˆν•„μš”ν•œ μΈμŠ€ν„΄μŠ€ ν”„λ‘œνΌν‹°(ꡬ체적인 데이터)κ°€ 남지 μ•Šλ„λ‘ ν•΄μ•Ό ν•œλ‹€.

방법 1: μΈμŠ€ν„΄μŠ€ 생성 ν›„ ν”„λ‘œνΌν‹° 제거

μƒμœ„ 클래슀의 μΈμŠ€ν„΄μŠ€(ν•˜μœ„ 클래슀의 prototype 객체)λ₯Ό λ§Œλ“  ν›„ ν•˜μœ„ ν΄λž˜μŠ€κ°€ ꡬ체적인 데이터λ₯Ό μ§€λ‹ˆμ§€ μ•Šλ„λ‘ κ·Έ ν”„λ‘œνΌν‹°λ₯Ό μ œκ±°ν•œλ‹€.
μ΄ν›„λ‘œ λ³€κ²½ ν˜Ήμ€ μ‚­μ œν•  수 없도둝 Object.freeze()λ₯Ό μ‚¬μš©ν•œλ‹€.

delete Square.prototype.width;
delete Square.prototype.height;
Object.freeze(Square.prototype);

방법 2: 빈 ν•¨μˆ˜ ν™œμš©

var Bridge = function () {}; // 빈 μƒμ„±μž ν•¨μˆ˜
Bridge.prototype = Rectangle.prototype;
Square.prototype = new Bridge();
Object.freeze(Square.prototype);

방법 3: Object.create() ν™œμš©

ν•˜μœ„ 클래슀의 prototype의 __proto__κ°€, μƒμœ„ 클래슀의 prototype을 μ°Έμ‘°ν•˜λ˜, (ν•˜μœ„ ν΄λž˜μŠ€κ°€ ꡬ체적인 데이터λ₯Ό μ§€λ‹ˆμ§€ μ•Šλ„λ‘) μƒμœ„ 클래슀의 μΈμŠ€ν„΄μŠ€κ°€ λ˜μ§€λŠ” μ•Šλ„λ‘ ν•œλ‹€.

...
Square.prototype = Object.create(Rectangle.prototype);
Object.freeze(Square.prototype);
...

(3) constructor λ³΅κ΅¬ν•˜κΈ°

μœ„μ—μ„œ μ‚΄νŽ΄λ΄€λ“―μ΄ SubClass.prototype.constructorκ°€ SuperClassλ₯Ό 가지고 μžˆμ–΄μ„œ SubClass.constructorλ₯Ό μ‹€ν–‰ν•˜λ©΄ μ˜λ„μ™€ λ‹€λ₯Έ κ²°κ³Όκ°€ λ‚˜μ˜¨λ‹€.
클래슀 상속 및 좔상화λ₯Ό μœ„ν•΄ μΆ”κ°€μ μœΌλ‘œ SubClass.prototype.constructorκ°€ SubClassλ₯Ό μ°Έμ‘°ν•˜λ„λ‘ ν•΄μ•Ό ν•œλ‹€.
λ²”μš©μ„±μ„ κ³ λ €ν•œ μ½”λ“œμ— μ•„λž˜ μ½”λ“œλ₯Ό μΆ”κ°€ν•˜λ„λ‘ ν•œλ‹€.

SubClass.prototype.constructor = SubClass;

4) ES6의 클래슀 및 클래슀 상속

var Rectangle = class {
  constructor (width, height) {
    this.width = width;
    this.height = height;
  }
  getArea () {
    return this.width * this.height
  }
};

var Square = class extends Rectangle {
  constructor (width) {
    super(width, width);
  }
  getArea () {
    console.log("size is : ", super.getArea());
  }
};

μƒμœ„ 클래슀λ₯Ό μƒμ†λ°›λŠ” ν•˜μœ„ 클래슀λ₯Ό λ§Œλ“€κΈ° μœ„ν•΄ class λͺ…λ Ήμ–΄ 뒀에 'extends μƒμœ„ 클래슀 이름'을 μΆ”κ°€ν–ˆλ‹€.

constructor λ©”μ„œλ“œ λ‚΄λΆ€μ—μ„œ super ν‚€μ›Œλ“œλ₯Ό 'ν•¨μˆ˜'처럼 μ‚¬μš©ν•  수 μžˆλŠ”λ°, μ΄λŠ” μƒμœ„ 클래슀의 constructor(μƒμ„±μž ν•¨μˆ˜)λ₯Ό μ‹€ν–‰ν•œλ‹€.

constructor λ©”μ„œλ“œλ₯Ό μ œμ™Έν•œ λ‹€λ₯Έ λ©”μ„œλ“œμ—μ„œλŠ” super ν‚€μ›Œλ“œλ₯Ό '객체'처럼 μ‚¬μš©ν•  수 μžˆλ‹€.
μ΄λ•Œ κ°μ²΄λŠ” μƒμœ„ 클래슀의 prototype 객체λ₯Ό μ°Έμ‘°ν•œλ‹€.
κ·ΈλŸ¬λ‚˜, ν˜ΈμΆœν•  λ©”μ„œλ“œ λ‚΄λΆ€μ—μ„œμ˜ thisλŠ” μ›λž˜μ˜ this(즉, ν•˜μœ„ 클래슀의 prototype 객체)λ₯Ό κ·ΈλŒ€λ‘œ λ”°λ₯Έλ‹€.


✨ 내일 ν•  것

  1. 볡슡 및 정리
profile
dev log

0개의 λŒ“κΈ€

κ΄€λ ¨ μ±„μš© 정보

Powered by GraphCDN, the GraphQL CDN