[JS] Object prototypes, 상속

Yoon·2021년 7월 25일
0

Javascript

목록 보기
6/8

Prototype

Javascript에서는 객체를 상속하기 위하여 프로토타입이라는 방식을 사용한다.

Java, C++과 같은 클래스 기반 객체지향 프로그래밍 언어와 달리 자바스크립트는 프로토타입 기반 객체지향 프로그래밍 언어이다.
이는 모든 객체들이 메소드와 속성들을 상속받기 위한 템플릿으로써 '프로토타입 객체(prototype object)'를 가진다는 의미이다.
프로토타입 기반 언어는 객체 원형인 프로토타입을 이용하여 새로운 객체를 만들어낸다. 이렇게 생성된 객체 역시 또 다른 객체의 원형이 될 수 있다.

  • 자바스크립트의 모든 객체는 자신의 부모 역할을 담당하는 객체와 연결되어 있다. 이는 마치 객체 지향의 상속 개념과 같이 부모 객체의 프로퍼티 또는 메소드를 상속받아 사용할 수 있게 한다.
    => 이러한 부모 객체를 'Prototype(프로토타입)객체 또는 프로토타입' 이라 한다.

  • 프로토타입 객체는 생성자 함수에 의해 생성된 각각의 객체에 공유 프로퍼티를 제공하기 위해 사용한다.

  • 프로토타입 체인(prototype chain) : 프로토타입 객체도 또 다시 상위 프로토타입 객체로부터 메소드와 속성을 상속 받을 수 있고, 그 상위 프로토타입도 또한 마찬가지로 상속받을 수 있다.
    => 객체 인스턴스와 프로토타입 간에 연결이 구성되며 이 연결을 따라 프로토타입 체인을 타고 올라가며 속성과 메소드를 탐색한다. 즉, 상속은 계속 이어질 수 있다.

  • 객체 안에는 proto(비표준) 속성이 있다. 이 속성은 객체가 만들어지기 위해 사용된 원형인 프로토타입 객체를 숨은 링크로 참조하는 역할을 한다. 많은 브라우저들이 생성자의 prototype 속성에서 파생된 proto 속성으로 객체 인스턴스에 구현하고 있다.

  • 객체를 생성할 때 프로토타입은 결정되어 결정된 프로토타입 객체는 다른 임의의 객체로 변경 가능하다. 이는 부모 객체인 프로토타입을 동적으로 변경할 수 있다. 이러한 특징을 활용해 객체의 상속을 구현할 수 있다.

var student = {
  name: 'Lee',
  score: 90
}
console.log(student.__proto__ === Object.prototype); // true

student 객체는 proto 프로퍼티로 자신의 부모 객체(프로토타입 객체)인 Object.prototype을 가리키고 있다.

예제

//프로토타입, 상속 예제

//상위 객체인 car 만들어줌.
const car = {
    wheels : 4,
    drive(){
        console.log("drive..");
    },
};

const bmw = {
    color: "red",
    navigation: 1,
}
const benz = {
    color: "black",
}
const audi = {
    color: "blue",
}
bmw.__proto__ = car; //car가 bmw객체의 프로토타입이 된다. = bmw는 car의 상속을 받는다.
benz.__proto__ = car;
audi.__proto__ = car;

console.log(bmw.color);//red

//bmw에서 wheels찾고 없으면 prototype에서 탐색
console.log(bmw.wheels);//4 //상속




//상속은 계속 이어질 수 있다. =>프로토타입 체인
const x5 = {
    color:"white",
    name:"x5",
}
x5.__proto__=bmw;//x5는 bmw를 상속

//객체의 프로퍼티 순회(for..in)
for(p in x5){
    console.log(p);
  //상속된 프로퍼티까지 모두 출력
    //color
    //name
    //navigation
    //wheels
    //drive
}
Object.keys(x5);//"color","name" //상속된 프로퍼티는 나오지 않음
//예제 .prototype사용
const Bmw = function (color){
    this.color = color;
};

//이렇게 해주면 생성자 함수에 일일이 .__proto__적용 안해도 됨 (x5.__proto__ = car처럼)
//하나씩 prototype 지정해 주는게 좋아 constructor때문
//new Bmw (생성자)를 통해 만들어진 객체의 __proto__ 내부에 wheels : 4 가 들어가
Bmw.prototype.wheels = 4;
Bmw.prototype.drive = function(){
    console.log('drive..');
};
/*이렇게 써도 동일하지만 이렇게 쓰면 constructor가 사라짐
Bmw.prototype = {
	//constructor : Bmw, //이렇게 생성자 직접 명시해주면 사용 가능
    wheels : 4,
    dirve(){
        console.log('drive..');
    },
}
*/
const x5 = new Bmw("red");
const z4 = new Bmw("blue");
console.log(x5.wheels)//4
console.log(x5.drive())//drive..

//생성자가 새로운 객체를 만들어야 할때, 그 객체는 생성자의 instance
//instanceof연산자 : 객체와 생성자 비교할 수 있고 해당객체가 그 생성자로부터 생성된 것이면 true
console.log(z4 instanceof Bmw);//true
console.log(z4.constructor === Bmw);//true

//클로져 이용하면 초기에 세팅해둔 color값을 얻을 수만 있고 변경 불가
const Bmw = function (color){
    const c = color;
    this.getColor = function(){
        console.log(c);
    }
}
const x5 = new Bmw('red');

더 자세히 참고해보기 : https://poiemaweb.com/js-prototype

profile
FE Developer✨

0개의 댓글