본문 바로가기

Language/Javascript

[Javascript] 상속, 프로토타입(Prototype)

728x90
반응형
const user = {
    name : 'Mike'
}

user.name;  // "Mike"
user.hasOwnProperty('name');  // true
user.hasOwnProperty('age');   // false

hasOwnProperty는 자신이 프로퍼티를 가지고 있는지 확인하는 함수이다. user 객체에 name이라는 프로퍼티가 있으므로 true가 나오고, age라는 프로퍼티는 없으므로 false가 나온다. 

 

hasOwnProperty는 만든 적이 없는데 어디에 있는 것일까?

__proto__라는 객체에 들어있다. 객체에서 프로퍼티를 찾으려고 하는데 없으면 여기에서 찾는다.

 

const user = {
    name : 'Mike'
    hasOwnProperty : function(){
        console.log('haha');
    }
}

user.hasOwnProperty();  // haha

hasOwnProperty라는 메소드가 객체 안에 만들면 어떻게 될까? 직접 만든 메소드가 동작한다.

객체에 프로퍼티가 있으면 탐색을 멈추고, 없을 때만 Prototype 객체에서 찾는다.

 

 

또 다른 예시이다. 프로토타입이 어떻게 동작하는지 보기 위해 상속이라는 개념을 이용해보겠다.

const bmw = {
    color: "red",
    wheels: 4,
    navigation: 1,
    drive(){
        console.log("drive..");
    }
};

const benz = {
    color: "black",
    wheels: 4,
    drive(){
        console.log("drive...");
    },
};

const audi = {
    color: "blue",
    wheels: 4,
    drive(){
        console.log("drive...");
    },
};

bmw, benz, audi의 wheels과 drive는 동일하다. 이렇게 공통된 부분은 Prototype을 통해 해결할 수 있다.

 

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;
benz.__proto__ = car;
audi.__proto__ = car;

공통된 부분을 car 객체로 만들고 car을 bmw, benz, audi의 프로토타입으로 설정했다. bmw, benz, audi는 car의 상속을 받는 것이다.

 

bmw.wheels를 작성하면 bmw 객체 내부에서 wheels 프로퍼티를 찾고, 찾으면 탐색을 멈춘다.

없으면 프로토타입에서 확인한다.

 

 

const car = {
    wheels: 4,
    drive(){
        console.log("drive..");
    },
};

const bmw = {
    color: "red",
    navigation: 1,
};

bmw.__proto__ = car;

const x5 = {
    color: "white",
    name: "x5",
};

x5.__proto__ = bmw;

상속은 계속 이어질 수 있다. x5는 bmw를 상속한다.

x5.navigation을 입력하면 x5에서 navigation을 찾고, 없으니까 x5의 프로토타입인 bmw에서 탐색한다. 이곳에도 없으면까 bmw의 프로토타입인 car에서 탐색해서 찾는다. 이것을 Prototype Chain이라고 한다.

 

for..in을 통해 객체의 프로퍼티들을 순회하면 모든 프로퍼티들이 나온다.

 

name과 color을 제외하고는 프로토타입에서 정의한 프로퍼티이다.

Object.keys나 Object.values를 사용하면 상속된 프로퍼티가 안 나온다.

 

for..in문에서 구분하고 싶다면 hasOwnProperty를 사용하면 된다.

 

 

const car = {
    wheels = 4,
    drive(){
        console.log("drive..");
    },
}

const Bmw = function(color){
    this.color = color;
};

const x5 = new Bmw("red");
const z4 = new Bmw("blue");

x5.__proto__ = car;
z4.__proto__ = car;

위 코드처럼 객체를 만들 때마다 프로토타입을 선언하는 것이 귀찮기 때문에

const Bmw = function(color){
    this.color = color;
};

Bmw.prototype.wheels = 4;
Bmw.prototype.drive = function(){
    console.log("drive...");
}

const x5 = new Bmw("red");
const z4 = new Bmw("blue");

이렇게 바꿔 쓸 수 있다.

 

생성자 함수가 새로운 객체를 만들어 낼 때 그 객체는 생성자의 인스턴스라고 불린다. 

이를 편리하게 확인할 수 있는 instanceof라는 연산자가 있다. instanceof를 이용해서 객체와 생성자를 비교할 수 있고, 이는 객체가 그 생성자로부터 생성된 것인지를 판단해서 true/false를 반환한다.

 

또한 인스턴스에는 어떤 생성자로부터 만들어졌는지 확인할 수 있는 constructor라는 프로퍼티가 존재한다. 

728x90
반응형