7. 프로토타입

gugyeoj1n·2022년 4월 26일
0

자바스크립트

목록 보기
7/9

수강하면서 처음 들어 본 개념이 엄청 많다. 프로토타입도 처음 들어본다. 내가 아는 프로토타입은 메이플스토리 메카닉밖에 없는데

생성자 함수와 프로토타입, 인스턴스의 관계

우리는 new 연산자로 생성자 함수를 사용해 새 인스턴스를 만들어 낸다. 그 인스턴스에는 생성자 Constructorprototype 이라는 프로퍼티 내용이 [[Prototype]] 이라는 프로퍼티로 참조가 전달된다. Constructor.prototypeinstance[[Prototype]] 이 동일하다는 뜻이다. [[Prototype]] 은 read 권한만 존재해서 실제 동작 상으로는 instance 와 [[Prototype]] 을 동일하게 여긴다.

예시로 자바스크립트 속에서 배열을 생성할 때, 리터럴 또는 new Array 를 사용한다. 모두 생성자 함수를 사용한 것과 같은데, 생성자 함수 Array 에는 prototype 을 포함한 여러 프로퍼티가 들어있다. prototype 은 객체이고 그 안에는 concat, filter, findIndex 등 배열에 관련된 메서드가 다 들어있다. 이는 console.log 로 확인할 수 있다. 배열 객체를 하나 생성하고 출력해 보면 [[Prototype]] 을 열어볼 수 있다. 내용은 Array.prototype 과 정확히 일치한다.

근데 숫자 리터럴은 객체가 아닌데 메서드를 쓸 수 있다. 자바스크립트가 임시로 숫자 리터럴에 해당하는 Number 생성자 함수의 인스턴스를 만들고, Number.prototype 속 메서드를 한번 사용하고 인스턴스를 다시 제거해 주기 때문이다. 문자열같은 다른 기본형 타입도 마찬가지이다. 반대로 참조형 데이터들은 선언할 때부터 객체이니 기본형처럼 복잡하게 메서드를 사용하지 않는다. 타입에 관계없이 데이터 자체에는 메서드가 들어있지 않지만, 생성자 함수의 prototype 을 [[Prototype]] 으로 연결해 거기 들어있는 메서드를 끌어와 사용할 수 있다는 뜻이다.

메서드 이쁘게 만들기

function Person(n, a) {
	this.name = n;
  	this.age = a;
}

var a = new Person('에이', 1);
var b = new Person('비', 3);

a.getAge = function() { return this.age; }
a.setOlder = function() { this.age += 1; }
b.getAge = function() { return this.age; }
b.setOlder = function() { this.age += 1; }

간단하게 Person 생성자를 짜고 a 와 b 객체를 만들어 주었다. 밑에는 메서드도 있다. 근데 메서드를 만든 부분이 너무 지저분하다. 코딩의 핵심은 간결함인데 이렇게 중복이 많으면 보기 안 좋다.

function Person(n, a) {
	this.name = n;
  	this.age = a;
}

Person.prototype.setOlder = function () { return this.age; }
Person.prototype.getAge = function () { this.age += 1; }

var a = new Person('에이', 1);
var b = new Person('비', 3);

그래서 두 메서드를 Person 생성자 함수의 prototype 안으로 옮겨 보았다. 이제 인스턴스를 생성하면 얼마든지 prototype 을 참조해 메서드들을 마음껏 쓸 수 있게 되었다. 코드 중복이 줄어든 것 외에도, 인스턴스는 고유한 정보만 갖고 있으면 되니 메모리 효율에도 도움이 되고 prototype 만으로 Person 인스턴스 집단의 특징을 한눈에 알아볼 수 있다.

체이닝 Chaining

생각해 보면 prototype 도 객체이다. prototype 은 Object 생성자 함수의 new 연산자로 생성된 인스턴스이고, Object 의 prototype 과 [[Prototype]] 으로 연결되어 있다. 만약 내가 Array 생성자로 인스턴스 A를 만들었다면, 인스턴스 A는 Object 의 prototype 까지 닿을 수 있는 것이다. 이것을 프로토타입 체인이라고 부른다. 수많은 인스턴스들의 머리 꼭대기에 있는 Object.prototype 에는 자바스크립트 전체를 통괄하는 공통된 메서드들이 정의되어 있다. 이 때문에 prototype 안에 객체 전용 메서드를 만들어 두어도 다른 데이터들이 그 메서드에 손댈 수 있기 때문에 객체 전용으로 부를 수가 없다. 그래서 values 같은 메서드들을 prototype 에 넣지 않고 생성자 함수에 직접 정의하게 되었다.


정리해 보자. Constructor 들은 prototype 프로퍼티를 갖고 있고, Constructor 로 새 인스턴스를 만들면 Constructor.prototype 이 [[Prototype]] 으로 인스턴스에 연결된다. 인스턴스는 [[Prototype]] 덕분에 Constructor.prototype 속 메서드를 자유롭게 사용할 수 있다. prototype 역시 객체이기에 연결된 상위 prototype 이 존재하고, 최상위 prototype 은 Object 생성자 함수가 갖고 있다.





메이플스토리 메카닉이랑은 차원이 다른 매우 유용한 정보였다. 재밌다.
그나저나 개념을 익히는 것도 좋지만 이걸 실제 코딩에 써먹을 수 있을까? 문법만 따지지 말고 눈에 보이지 않는 구조도 최대한 생각하는 습관을 들여야겠다.

이제 강의가 하나 남았다. 이거 끝나면 다시 리액트로 돌아갈 계획인데, 처음부터 다시 할 거다. 파이썬은 학교 수업으로 듣기도 했고 워낙 오래 만진 친구라 자유자재로 쓸 수 있지만 요새 공부하는 프론트엔드 스택들은 여기저기 찾아 보면서 복붙해야 된다. 어찌 보면 당연한 거지만 빈 프로젝트에서 뼈대부터 내가 유연하게 개발할 수 있을 만큼의 실력을 갖고 싶다. 벨로그도 시작했으니 헷갈리거나 중요하다 싶은 내용들은 기록해 두면서 공부해야겠다. 기록을 남기는 습관이 여러모로 참 도움이 많이 된다

음주단속 이렇게 늦게 출발하는 거 처음이다. 빨리 돌아오길 바라며 오늘은 run

0개의 댓글