티스토리 뷰

Prototype?

의미

  • prototype: 원형, 견본
  • 어떠한 객체가 만들어지기 위해 그 객체의 모태가 되는 오브젝트를 의미한다.
  • 모든 함수 객체의 생성자는 prototype 프로퍼티를 가지고 있다.

객체 생성

  • 함수는 생성자로 대응되며 각 객체에서 공유되어 사용할 프로퍼티 및 함수는 prototype 객체에 넣어서 사용한다.
  • 객체 생성시 new키워드를 사용하여 생성한다.
// 생성자 함수
function Person (name) {
  // 이름을 객체에 초기화한다.
  this.name = name;
}
 
// 객 객체에서 공유될 함수인 getName()을 prototype에 정의한다.
Person.prototype.getName = function () {
  return this.name;
}
 
const person1 = new Person('jin.bak');
console.log(`person1 name is ${person1.getName()}`);
 
const person2 = new Person('anonymous');
console.log(`person2 name is ${person2.getName()}`);

객체 생성 원리

  • new키워드를 사용하여 객체 생성시 아래와 같이 진행된다.
// new Person('jin');은 아래와 같이 진행된다.
const person1 = {}; // person1로 빈 객체를 생성한다.
person1.__proto__ = Person.prototype; // __proto__ (숨겨진)프로퍼티에 Person의 prototype을 대입한다.
Person.call(person1, 'jin'); // person1 객체를 바인딩하여 Person함수를 실행한다.
 
console.log(`person1 name is ${person1.getName()}`);

__proto__

  • prototype과 __proto__는 다른 개념.
  • prototype 속성은 함수만 가지고 있고 __proto__는 모든 객체가 가지고 있는 속성.
  • __proto__는 객체가 생성될 때 조상이었던 함수의 Prototype Object를 가리킨다.
    • 이로 인해 위의 예제에서 person1이 getName()을 호출할 수 있다.
  • 모든 인스턴스는 Object.prototype와 연결되어 있다.

prototype chain

  • 인스턴스에서 특정 프로퍼티가 없을경우 __proto__를 따라 상위 오브젝트로 올라가며 찾는다.
  • 상위에 프로퍼티가 해당 프로퍼티를 반환하며 Object.prototype까지 올라가서도 찾지 못한다면 undefined를 반환한다.

예) 위의 person1.getName() 호출시 - 실제 빨간선을 따라 체인이 실행된다.

상속

prototype 상속

  • 위의 prototype의 특성을 이용해 OOP의 상속을 자바스크립트에서도 흉내낼수 있다.
  • 자식개체와 상위객체의 prototype을 이어주어 상속과 같이 동작 하도록 만든다.
function Person (name) {
  this.name = name;
}
 
Person.prototype.printName = function () {
  console.log(`person name is ${this.name}`);
}
 
function Teacher (name, subject) {
  // 현재 컨텍스트로 조상 클래스(Person)를 실행한다.
  Person.call(this, name);
  this.subject = subject;
}
 
// Person prototype과 이어진 새로운 임시 객체를 만들어 Teacher의 prototype에 할당한다.
// 상위 객체와 하위객체를 이어주는 부분임.
// Object.create로 만들수도 있음.
// Teacher.prototype = Object.create(Person.prototype);
function F () {}
F.prototype = Person.prototype;
Teacher.prototype = new F();
 
// 위의 임시 함수인 F의 constructor가 덮어써졌으므로 재할당 해준다.
Teacher.prototype.constructor = Teacher;
 
// override
Teacher.prototype.printName = function () {
  console.log(`teacher name is ${this.name}`);
}
 
Teacher.prototype.printSubject = function () {
  console.log(`teacher subject is ${this.subject}`);
}
 
const p = new Person('person jin');
p.printName(); // person name is person jin
 
const t = new Teacher('teacher jin', 'computer');
t.printName(); // teacher name is teacher jin
t.printSubject(); // teacher subject is computer

ES6 클래스

  • ES6문법에서는 기존 OOP 언어들의 형식과 비슷하게 클래스를 만들어 사용할 수 있다.
  • 하지만 내부적으로는 위의 방식과 동일하게 동작하며 개발 및 가독성 측면에서 축약으로 만들어 졌다.
class Person {
  constructor (name) {
    this.name = name;
  }
 
  printName () {
    console.log(`person name is ${this.name}`);
  }
}
 
class Teacher extends Person {
  constructor (name, subject) {
    super(name);
    this.subject = subject;
  }
 
  printName () {
    console.log(`teacher name is ${this.name}`);
  }
 
  printSubject () {
    console.log(`teacher subject is ${this.subject}`);
  }
}
 
 
const p1 = new Person('person jin');
p1.printName(); // person name is person jin
 
const t1 = new Teacher('teacher jin', 'computer');
t1.printName(); // teacher name is teacher jin
t1.printSubject(); // teacher subject is computer

출처

'개발 언어 > NodeJS' 카테고리의 다른 글

NodeJS - Socket IO  (0) 2020.02.28
비동기 프로그래밍  (0) 2020.01.11
자바스크립트 - ES6문법  (0) 2019.07.27
자바스크립트 - 객체  (0) 2019.07.27
자바스크립트 - 매개변수  (0) 2019.07.27
댓글