[JS] 프로토타입

Urther·2021년 12월 7일
0

JavaScript

목록 보기
1/8

프로토타입이란?

자바스크립트는 프로토타입을 기반으로 상속을 구현한다.

모든 객체는 [[prototype]] 이라는 내부 슬롯을 가지고 있다. [[prototype]] 에 직접적으로 접근은 어렵지만 __proto__ 라는 접근자 프로퍼티를 통해 간접적으로 접근할 수 있고 __proto__ 을 통해 간접적으로 자신의 상위 프로토타입을 알 수 있다.

__proto__ 가 null 인 경우는 프로토타입 체인의 종점이다.

사용하는 이유

코드의 재사용

프로토타입을 통해 상속이 가능해진다.

만약 JS가 상속을 지원하지 않는 언어였다면

function Circle(radius){
  this.radius = radius;
  this.getArea = function(){
    return Math.PI * this.radius ** 2;
  };
}
const new Circle = new Circle(3);
const new Circle = new Circle(4);

겹치는 getArea() 라는 메서드를 Circle1, Circle2 에 중복 생성시켰어야 한다. 하지만, 프로토타입을 통해 상속이 가능하기 때문에 getArea() 메서드를 Circle.prototype에 담아주면 Circle에는 자신의 식별자만 가지면 된다.

Circle.prototype.getArea = function(){
  return Math.PI * this.radius ** 2 ;
}

우와 같은 방법으로 getArea라는 메서드를 Circle.prototype 에 추가해주면 Circle.prototype에 공통적으로 getArea 메서드를 갖고, Circle1 과 Circle2 는 각자의 radius 만 가질 수 있다.

프로토타입 체인을 통한 프로퍼티, 메서드 검색 용이

자바스크립트 엔진은 프로토타입 체인을 통해 프로퍼티/메서드를 검색하고, 스코프체인을 통해 식별자를 검색한다.

me.hasOwnProperty('name');

me 는 hasOwnProperty라는 메서드를 가지고 있지만 프로토타입을 통해 상속을 받았기 때문에 hasOwnProperty 메서드를 사용할 수 있다.

자바스크립트 엔진에서는 어떤 과정을 거쳐 메서드를 검색할까?

  • me라는 객체에 hasOwnProperty 가 없기 때문에 프로토체인을 따라 메서드를 검색한다. me 객체 상위 프로토타입은 Person.prototype에도 hasOwnProperty가 존재하지 않으니 Person.prototype의 프로토타입을 체크하여 Object.prototype에서 hasOwnProperty 메서드를 찾는다.

    만약 Object.prototype 에 그 메서드가 없어도 오류 를 출력하는 것이 아닌 undefined 를 출력한다.

프로토타입의 문제점

prototype 접근 가능

function Person (name) {
	this.name = name;
}
Person.prototype.sayHello=function(){
	console.log(` hi my name is ${this.name}`);
};

const me=new Person('lee');

프로토타입 프로퍼티를 삭제하기 위해 (이럴 일이 없게끔 처음부터 삭제할 프로퍼티를 안만드는 것이 best다.) me를 통해 접근하는 것이 아니라, Person.prototype.sayHello 로 직접 접근이 가능하다는 것이다.


삭제 뿐만 아니라 자신의 상위 프로토타입을 직접 지정해줄 수 있다.

이렇게 상속관계를 동적으로 변경할 수 있다는 것은 가독성을 떨어 뜨리고, 추가적인 연결 ― Person 과 Person.prototype 의 연결이 끊어진 경우 ― 을 도와주는 코드가 필요하다. (상속 관계를 바꾸는 것은 대부분 안티패턴)
+ 상속관계이기 때문에 하나 잘못 건들이면 이미 생성되었고, 생성될 객체에게 모두 영향을 준다.

this의 이용

프로토타입을 쓰면 this를 써야하는데 자바스크립트의 this는 함수가 호출되는 방식에 따라 동적으로 바인딩된다. 그래서 문제점이다.

  1. 일반 함수로 호출되는 경우 : 전역 객체가 this다.
  2. 메서드로 호출되는 경우 : 메서드를 호출한 객체가 this다.
  3. 생성자 함수로 호출되는 경우 : this는 생성자 함수가 생성 인스턴스가 된다.

코드 내에서 this가 어떤 this를 의미하는지 찾아야하기 때문에 가독성이 떨어질 수 있다.

그래서 ?

당연한 이야기지만 시기에 맞춰 잘 이용한다. 상속이 필요하지 않는다면 굳이 프로토타입으로 구현하지 않아도 된다. ― 상속이 필요할 때가 그렇게 많았나?! 라는 생각이 있다.


reference |
poiemaweb - 모던자바스크립트
MeetUp - 쉽게 이해하는 자바스크립트 프로토타입 체인
[JS 프로토타입] 자바스크립트의 프로토타입 훑어보기

profile
이전해요 ☘️ https://mei-zy.tistory.com

0개의 댓글