Front-End/JavaScript

프로토타입 (Prototype)과 객체지향 프로그래밍

Voyage_dev 2024. 3. 25. 00:12
function Work(indicator) {
  this._indicator = indicator ?? 0;
}

Work.prototype.start = function () {
  setInterval(() => {
		this._indicator += 10;
    this._draw();
	}, 1000);
}

Work.prototype._draw = function () {}

function WorkA() { Work.call(this, 0); }

WorkA.prototype = Object.create(Work.prototype, {});
WorkA.prototype._draw = function () { /* linear progress drawing logic */ };

function WorkB() { Work.call(this, 10); }

WorkB.prototype = Object.create(Work.prototype, {});
WorkB.prototype._draw = function () { /* linear progress drawing logic */ };

const workA = new WorkA();
const workB = new WorkB();

workA.start();
workB.start(); 
💡 이번 페이지에서 우리는 Javascript 프로토타입 개념에 대해 복기하는 시간을 가져보자.

https://youtu.be/yXnbvyl04V4?si=ARe7eejhO-lWQitT

https://youtu.be/673mZ8rE9UY?si=u8xcqzDIeavjBpLl

자바스크립트의 프로토타입 개념이 생소하다면 위 영상을 통해 개념을 한번 짚고 넘어가자 프로토타입은 무엇인지, 프로토타입 체이닝은 어떤 개념인지 살펴보실 수 있다.


프로토타입이란?

  • 자바스크립트는 프로토타입 기반 언어이다. 즉, 객체를 생성할 때, 그 객체는 자신의 부모 역할을 하는 프로토타입 객체를 가르키는 [[Prototype]]라는 내부 슬롯을 갖는다. 클래스 처럼 객체의 인스턴스를 위한 명세와 같은 역할을 하는데 객체 본인만이 가진 속성과 메서드에도 접근할 수 있으면서 프로토타입에도 접근할 수 있다.
function Person() {}

// new 키워드로 함수를 호출할 때 마다 생성되는 인스턴스는 함수 프로토 타입의 모든 속성을 상속한다
let person1 = new Person(); 

console.log(Person.prototype === person1.__proto__);

위 코드에서 Person.prototype은 Person 함수를 통해 생성된 객체의 부모 역할을 하는 프로토타입 객체이다. person1.__proto__는 person1 객체의 부모 역할을 하는 프로토타입 객체를 가르킨다. 따라서 Person.prototype과 person1.__proto__는 같은 객체를 가르킨다.

네이티브 객체 프로토타입

  • 자바스크립트의 Array, String 등의 내장 객체 역시 자신의 프로토타입을 가지고 있다
  • 배열을 선언해 늘 사용하던 map, filter 등을 사용해 조작하고 문자열을 선언해 split 등의 연산을 할 수 있게 해주는 이유이다

const arr = [1,2,3,4,5];
console.log(Object.getPrototypeOf(arr))  //Array prototype
const str = "Hello world!";
console.log(Object.getPrototypeOf(str)) //String prototype
const date = new Date();
console.log(Object.getPrototypeOf(date)) //Date prototype

프로토타입 체이닝

  • 프로토타입 체이닝은 객체의 속성을 참조하거나 메서드를 호출할 때, 해당 객체에 해당 속성이나 메서드가 없다면[[Prototype]]이 가리키는 링크를 따라 자신의 부모 역할을 하는 프로토타입 객체의 속성이나 메서드를 참조하거나 호출하는 것을 의미한다. 즉, 다른 객체에서 정의된 메서드와 속성을 한 객체에서 사용할 수 있게 해준다.
function Person() {}

Person.prototype.sayHello = function() {
    console.log('Hello');
};

let person1 = new Person();
person1.sayHello(); // Hello

위 코드에서 person1 객체는 sayHello라는 메서드를 갖고 있지 않지만, Person.prototype이라는 프로토타입 객체가 sayHello 메서드를 갖고 있다. 따라서 person1.sayHello()를 호출할 때 프로토타입 체이닝이 발생하여 Person.prototype의 sayHello 메서드가 호출한다.

이처럼 프로토타입과 프로토타입 체이닝을 통해 JavaScript는 객체 간 상속과 메서드 재사용을 가능하게 한다.

new 키워드를 사용할 때 발생하는 내부동작에 대해 조금 더 궁금증이 생긴다면 Javascript Variable Object라는 키워드를 찾아보자.

프로토타입을 사용하는 이유

  • 메모리 효율
    • 자바스크립트에서 모든 객체는 프로토타입을 공유한다. 객체 자체가 스스로 메서드와 속성을 모두 가지는 대신 여러 객체가 동일한 프로토타입을 공유하도록 하고 이를 사용하면 매모리를 효율적으로 사용할 수 있다.
  • 객체지향스러움
    • 프로토타입을 통해 클래스에서 상속해 사용하는 것 처럼 다른 객체로부터의 속성과 메서드를 사용할 수 있다. 이를 통해 코드 재사용이 가능해진다
  • 생산성
    • 프로토타입을 통해 동일한 속성, 동작이 필요한 여러 객체들마다 이를 직접 선언하고 개발할 필요 없이 프로토타입을 이용해 관리할 수 있다.

요약

  • prototype은 객체 생성자 함수에 의해 생성되는 객체들이 공유하는 속성과 메소드를 저장하는 특수 객체이다.
  • 모든 javascript 객체는 선언 할당하면 해당 생성자 함수의 prototype객체와 연결되며 프로토타입 체이닝을 통해 해당 객체의 속성, 메소드에 접근 가능하다.

 

참고문서


Object prototypes - Web 개발 학습하기 | MDN

[10분 테코톡] 💼 크리스의 Prototype