본문 바로가기

자바스크립트의 정석 🟡

자바스크립트 - 프로토타입

참고자료: 인프런 코어자바스크립트(프로토타입 편)

 

코어 자바스크립트 - 인프런 | 강의

ES6 이전까지의 자바스크립트 전체를 관통하는 핵심 개념들에 대하여, 전반적인 흐름을 살펴보는 강의입니다.,  📢 강의 리뉴얼 안내 2021.8.26 리뉴얼 강의가 섹션 0에 업데이트 되었습니다. 기존

www.inflearn.com

 

 

 

프로토타입 

이 그림을 이해하면, 프로토타입은 다 이해한거다. 난 아직 이해 못함

 

1)프로토타입

 

배열 인스턴스 [1,2,3]이 있다고 가정해보자

이 배열은 리터럴로 생성하든, array 생성자 함수로 생성한 배열이든, 일단 배열임 

이 배열은 array 생성자 함수로 생성될 것이고, array 함수에는  많은 프로퍼티들이 존재하는데 그 중에 프로토타입이라는 프로퍼티가 존재한다. 얘가 배열 리터럴에 [[prototype]]으로 연결되어 있는 거. 그리고 프로토타입이라는 프로퍼티는 객체다(?) 이 객체 안에서 다양한 프로퍼티가 존재한다.

이해하기 쉽게 말하면, array 생성자함수 안에 프로토타입이라는 프로퍼티가 있고 이 프로토타입안에는 또 다른 프로퍼티들이 존재. 그래서 프로토타입도 객체가 되는 것. 

이 배열함수를 들어가 보면 [[prototype]]이 존재한다. 이 안에 내용은 array.prototype내용과 똑같다. 

array라는 생성자 함수안에 prototype이라는 프로퍼티가 있는데, 이 프로퍼티 안에 constructor 프로퍼티가 있다. 말이 이상하지만 맞다 여기에는 array 함수가 담겨져 있다. 

즉, array.prototype.constructor에는 다시 array 생성자 함수가 존재하는 것이다. 

즉, array생성자 함수로 배열을 생성한 것은, array안에 prototype이라는 프로퍼티를 이용하여 배열이 생성된 것이다. 

 

 

 

만약, abc를 반복(repeat이라는 메서드 사용)하게 하는 메서드를 만든다고 생각하면 string 생성자 함수로abc를 만들고 string의 프로토타입을 이용하여 프로토타입 안에 프로퍼티를 사용하여 repeat이라는 메서드를 호출하는 것. 

 

다시말해, 데이터 자신에게는 메서드들이 없지만, 생성자 함수의 프로토타입이라는 프로퍼티를 가져와 [[prototype]]이라는 연결 통로를 만들어 쓸 수 있다는 거지!

 

 

참고로, 이거 다 같은 말 

 

 

 

2) 메소드 상속 및 동작원리 

function Person(n, a){
    this.name=n;
    this.age=a;
}
var roy = new Person('로이', 30);
var jay = new Person('제이', 25);

roy.setOlder=function(){
    this.age +=1;
}

roy.setAge=function(){
    return this.age;
}

jay.setOlder=function(){
    this.age +=1;
}

jay.setAge=function(){
    return this.age;
}

//dry - 최대한 반복되는 것을 줄이자
function Person(n, a){
    this.name=n;
    this.age=a;
}

Person.prototype.setOlder= function(){
    this. age+=1;
}
Person.prototype.setAge= function(){
    return this.age;
}
var roy = new Person('로이', 30);
var jay = new Person('제이', 25);

위에 코드와 밑에 코드를 보면, 확실히 밑에 코드가 짧아진 것을 볼 수 있다.

 프로토타입을 이용한다면, 코드를 짧아지고 하나의 문장으로 '사람은 누구나 나이를 먹고, 각자의 나이를 알 수 있다'라는 짧은 문장으로 내용을 설명할 수 있다.

 이는 메모리 용량도 줄이는 장점 또한 가지고 있음

 

 

 

3) 프로토타입 체이닝 

참고로 프로토타입은 모두 객체.

프로토타입은 object.prototype과 프로토타입 체인으로 연결되어 있음.

모든 데이터타입에 대해 [[prototype]]으로 연결된 object.prototype은 자바스크립트 모두를 통괄하는 공통된 메서드들이 존재. 

만약 object.prototype에 values라는 메서드가 정의되어 있다면, {a:1, b:2}.values로 되어 있겠지? 그러면 얘 말고도

new.Date().values , (10).values가 될거다. -> values라는 메소드를 타고. 이러면 객체 전용 메서드가 아니게 되버림 

 

 

그래서, object라는 객체 생성자 함수에 직접 메소드를 정의할 수 밖에 없음. 이러한 이유로 생성자함수의 프로퍼티를 넘겨주면서 object.명령어를 호출하면서, 매개변수로 객체 자신을 넘겨주는 경우가 많다. 이유는 프로토타입 체인 때문

 

array 배열의 [1,2,3]이라는 배열이 있을 때, 

이러면, 

[1,2,3].toString()을 하면 "1,2,3"이 나옴 array.prototype에 의해

그리고 delete Array.prototype.toString을 하고, 똑같이 [1,2,3].toString()라면 

object 생성자함수의 프로퍼티인 obkect.prototype으로 올라가 "[object Array]"가 나올 것이다. 

이는 object 생성자 함수의 프로토타입이라는 프로퍼티로 올라가 그 안에 있는 toString()이라는 메소드에 의해 결과 추출된 것. 

그렇다면, 여기에서도 delete Object.prototype.toString를 하고, [1,2,3].toString()는 에러가 발생한다. 

즉, 프로토타입의 체인된 현상을 증명한 격.