자바스크립트 끄적끄적

자바스크립트 프로토타입이란?

코딩질문자 2022. 8. 31. 16:59
728x90

상속(inheritance)

상속(inheritance)이란 새로운 클래스에서 기존 클래스의 모든 프로퍼티와 메소드를 사용할 수 있는 것을 의미합니다.

 

상속을 통해 새로운 프로그램의 요구에 맞게 기존 클래스를 수정하여 재사용할 수 있습니다.

또한, 클래스 간의 종속 관계를 형성함으로써 객체의 관계를 조직화할 수 있는 장점이 있습니다.

따라서 이러한 상속은 추상화, 캡슐화와 더불어 객체 지향 프로그래밍을 구성하는 중요한 특징 중 하나가 됩니다.

 

하지만 C#이나 C++과 같은 클래스 기반(class-based)의 객체 지향 언어와는 달리 자바스크립트는 프로토타입 기반(prototype-based)의 객체 지향 언어입니다.

프로토타입 기반이기 때문에 상속의 개념이 클래스 기반의 객체 지향 언어와는 약간 다릅니다.

자바스크립트에서는 현재 존재하고 있는 객체를 프로토타입으로 사용하여, 해당 객체를 복제하여 재사용하는 것을 상속이라고 합니다.

 

=> 쉽게 설명하면 자바스크립트를 처음에 배울때 최상위 프로토타입 object에 대해서 가르침을 받았을 텐데. 그 개념이라고 생각하면 될듯.

c++, java 배울 때 상속을 프로토타입이라고 하면 되는 구나라고 하면 일단은 이해하기 편할듯.


 

프로토타입(prototype)

자바스크립트의 모든 객체는 프로토타입(prototype)이라는 객체를 가지고 있습니다.

모든 객체는 그들의 프로토타입으로부터 프로퍼티와 메소드를 상속받습니다.

이처럼 자바스크립트의 모든 객체는 최소한 하나 이상의 다른 객체로부터 상속을 받으며, 이때 상속되는 정보를 제공하는 객체를 프로토타입(prototype)이라고 합니다.

 

var obj = new Object(); // 이 객체의 프로토타입은 Object.prototype입니다.

var arr = new Array();  // 이 객체의 프로토타입은 Array.prototype입니다.

var date = new Date();  // 이 객체의 프로토타입은 Date.prototype입니다.

=> 보면 알 수 있듯이 java, c++에서 인스턴스 생성하는걸아 일맥상통하는 것 같음.

 


프로토타입 체인(prototype chain)

자바스크립트에서는 객체 이니셜라이저를 사용해 생성된 같은 타입의 객체들은 모두 같은 프로토타입을 가집니다.

또한, new 연산자를 사용해 생성한 객체는 생성자의 프로토타입을 자신의 프로토타입으로 상속받습니다.

var obj = new Object(); // 이 객체의 프로토타입은 Object.prototype입니다.

var arr = new Array();  // 이 객체의 프로토타입은 Array.prototype입니다.

var date = new Date();  // 이 객체의 프로토타입은 Date.prototype입니다.

하지만 Object.prototype 객체는 어떠한 프로토타입도 가지지 않으며, 아무런 프로퍼티도 상속받지 않습니다.

또한, 자바스크립트에 내장된 모든 생성자나 사용자 정의 생성자는 바로 이 객체를 프로토타입으로 가집니다.

 

=> 앞서 말한 것 처럼 Object에 대한 설명..

 

=> Object를 찍어서 보면 여러 매서드가 있음을 알 수 있음.

c언어에서 #include <stdio.h> 처럼 이용하는 거고, 자바스크립트에서는 기본적으로 다음과 같은 라이브러리 매서드들이 프로토타입으로 최상단에 기본적으로 선언되어있따고 생각하면 될듯.

=> 대충 이런 그림같은 느낌?

var date = new Date(); // 이 객체는 Date.prototype 뿐만 아니라 Object.prototype도 프로토타입으로 가집니다.

 

위와 같이 프로토타입이 상속되는 가상의 연결 고리를 프로토타입 체인(prototype chain)이라고 합니다.

Object.prototype 객체는 이러한 프로토타입 체인에서도 가장 상위에 존재하는 프로토타입입니다.

따라서 자바스크립트의 모든 객체는 Object.prototype 객체를 프로토타입으로 상속받습니다.

 

=> 최상단이라는 개념이 있으니 프로토타입을 받아서 또 프로토타입을 만드는 형식이 취할 수 있고, 이런 경우에 프로토타입 체인이라고 이해하면 될듯.

 


객체에 프로퍼티 및 메소드 추가

이미 생성된 객체에 새로운 프로퍼티나 메소드를 추가하는 방법은 다음과 같습니다.

function Dog(color, name, age) {
    this.color = color;
    this.name = name;
    this.age = age;
}

var myDog = new Dog("흰색", "마루", 1);

myDog.family = "사모예드"; // 품종에 관한 프로퍼티를 추가함.

myDog.breed = function() {        // 털색을 포함한 품종을 반환해 주는 메소드를 추가함.

    return this.color + " " + this.family;

}

document.write("우리 집 강아지는 " + myDog.breed() + "입니다.");

 

위의 예제에서 새롭게 추가된 weight 프로퍼티와 breed() 메소드는 오직 myDog 인스턴스에만 추가됩니다.

이미 생성된 다른 Dog 객체나 차후에 생성되는 어떠한 다른 Dog 객체에도 추가되지 않습니다.

 

=> Dog 라는 프로토타입(객체)를 생성

var myDog = new Dog(); // 를 통해 인스턴스 생성.

또한 이미 선언해서 만든 인스턴스 프로토타입에 다음과 같이 재정의 할 수 있는듯 (오버라이딩이랑 느낌이 비슷)

myDog.family = '사모예드';

마찬가지로 새로운 매서드를 만드는것 다만 객체의 매서드의 value가 함수형태라는게 차이점.

myDog.breed = function() {....}

 


프로토타입에 프로퍼티 및 메소드 추가

프로토타입에 새로운 프로퍼티나 메소드를 추가하는 것은 객체에 추가할 때와는 다른 방법을 사용해야 합니다.

프로토타입의 경우에는 생성자 함수에 직접 추가해야만 이후에 생성되는 모든 다른 객체에도 적용할 수 있습니다.


function Dog(color, name, age) {
    this.color = color;
    this.name = name;
    this.age = age;

    this.family = "사모예드"; // 프로토타입에 프로퍼티를 추가할 때에는 기본값을 가지게 할 수 있음.

    this.breed = function() {
        return this.color + " " + this.family;
    };

}

var myDog = new Dog("흰색", "마루", 1);

var hisDog = new Dog("갈색", "콩이", 3);

document.write("우리 집 강아지는 " + myDog.family + "이고, 친구네 집 강아지도 " + hisDog.family + "입니다.");

=> 설명과 글이 조금 이해 안감...

코드는 프로토타입에 프로퍼티를 추가할 때 기본값을 가지게 하는 코드인데..

설명은 프로토타입에 추가 부분과 추가할 때 생성자함수에 직접 추가해야 한다는 글임..? 설명과 예시가 틀림 머지?

라고 생각할 수 있는데 프로토타입을 만든 인스턴스(?)에는 다음과 같이 프로퍼티를 추가했슴.

myDog.breed = function() {        // 털색을 포함한 품종을 반환해 주는 메소드를 추가함.

    return this.color + " " + this.family;

}

하지만 프로토타입에 직접 이와 같이 추가하려면 함수 내부에 추가해야 한다는 뜻임.

Q. constructor이 없는데영? 자바나 c++처럼 언어 자체가 실행될 때 기본값으로 만들어 주는듯. (확실 하진 않음..) + this를 쓴게 그 증거가 아닐까 생각함.

때문에 다음과 같이 내부에 만든것. 

this.family = "시베리안 허스키"; // 프로토타입에 프로퍼티를 추가할 때에는 기본값을 가지게 할 수 있음.

또한 추가함과 동시에 디폴트값도 넣을 수 있다는 설명인듯.

 


prototype 프로퍼티

prototype 프로퍼티를 이용하면 현재 존재하고 있는 프로토타입에 새로운 프로퍼티나 메소드를 손쉽게 추가할 수 있습니다.

function Dog(color, name, age) {

    this.color = color;

    this.name = name;

    this.age = age;

}

// 현재 존재하고 있는 Dog 프로토타입에 family 프로퍼티를 추가함.

Dog.prototype.family = "시베리안 허스키";

// 현재 존재하고 있는 Dog 프로토타입에 breed 메소드를 추가함.

Dog.prototype.breed = function() {

    return this.color + " " + this.family;

};

var myDog = new Dog("흰색", "마루", 1);

var hisDog = new Dog("갈색", "콩이", 3);



document.write("우리 집 강아지는 " + myDog.family + "이고, 친구네 집 강아지도 " + hisDog.family + "입니다.");

document.write("우리 집 강아지의 품종은 " + myDog.breed() + "입니다.<br>");

document.write("친구네 집 강아지의 품종은 " + hisDog.breed() + "입니다.");

=> 아까처럼 프로토타입 내부에 넣는 방법말고, prototype이라는 프로퍼티를 이용하면 다음과 같이 밖에서도 매서드를 추가할 수 있다는거임

 

Dog.prototype.family = "시베리안 허스키";

 

참고 사이트:

https://developer.mozilla.org/ko/

https://velog.io/@grinding_hannah

 

grinding_hannah (Dico) - velog

프린이의 코묻은 코드가 쌓이는 공간

velog.io

 

MDN Web Docs

The MDN Web Docs site provides information about Open Web technologies including HTML, CSS, and APIs for both Web sites and progressive web apps.

developer.mozilla.org


후기

 

엘리스 인터뷰때 질문했는데 그 때 정확히 기억하지 못한것들을 정리하고자 글을 씀.

알고있는 내용이지만 정확히 기억이 안나서 "모릅니다"라고 말했는데..

그레이한 기억을 확실하게 이번 기회에 알고 넘어가고자 다음과 같이 설명하는 글을 정리함.

이후 버블링과 캡쳐링, 자바스크립트 버전별 특징도 정리해서 올릴거임.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90