08. 프로토타입

양희준·2021년 11월 28일
0

JavaScript Info

목록 보기
8/19
post-thumbnail

📌 8-1 객체지향 프로그래밍이란?

시간의 흐름에 따라서 코드를 작성하는 절차적 프로그래밍이랑 반대되는 개념으로 모든 사물들을 객체로 표현하여 독립된 객체간의 소통으로 이루어진 프로그래밍이다.

📌 8-2 객체지향 프래그래밍의 특징 4가지

  1. 추상화
  • 사용자가 쉽게 사용할 수 있도록 프로그램에서 필요한 속성만 표현하는 것 즉 내부의 복잡한 내용들은 숨기고 필요한 내용만 보여주는 것이며 인터페이스가 간단해진다.
  1. 캡슐화
  • 연관된 변수와 함수들을 하나의 그룹으로 묶어 하나의 단위 즉 객체로 만드는 것이며 변수는 프로퍼티 함수는 메소드라고 생각하면 된다. 코드의 재사용성을 증가시킨다.
  1. 상속
  • 부모의 특징을 자식이 사용할 수 있으며 불필요한 코드사용을 줄일 수 있게 해준다.
  1. 다형성
  • 하나의 객체가 여러가지 타입을 가지는 특성으로 오버라이딩이 대표적이다.

📌 8-3 프로토타입이란?

자바스크립트에서는 클래스 기반의 객체지향 프로그래밍과는 다르게 프로토타입 기반의 객체지향 프로그래밍이 가능하며 상속을 구현하기 위해서 사용된다. 자바스크립트의 모든 객체는 자신의 부모 역할의 객체와 연결되어 있는데 이 부모 객체를 프로토타입이라 한다. 프로토타입에 의해 생성된 각각의 객체에 공유 프로퍼티를 제공한다.

🔥 객체 생성방식에 따라서 프로토타입이 결정된다.
🔥 자바스크립트는 원시값을 제외한 나머지 값은 모두 객체이며 [[Prototype]] 내부슬롯을 가진다.
🔥 인스턴스는 [[Prototype]]의 constructor 프로퍼티를 통해 생성자 함수에 접근할 수 있다.
🔥 생성자 함수는 자신의 prototype 프로퍼티를 통해서 접근한다.

📌 8-4 __proto__란?

모든 객체는 __proto__ 접근자 프로퍼티를 통해 자신의 프로토타입에 접근이 가능하다.
const car = {
    name: "K5"
};
// 객체 car의 [[Prototype]]에 접근
console.log(car.__proto__);

🔥 자바스크립트 내부슬롯에 접근이 원칙적으로는 불가능하지만 간접적으로 접근할 수 있도록 방법을 제공한다.

__proto__를 이용해서 프로토타입 교체

const car = {
    name: "K5"
};
const animal = {
    name1: "Dog"
};

// 프로토타입을 교체함
car.__proto__ = animal;
// 결과 : Dog 출력
console.log(car.name1);
const car = {
    name: "K5"
};
const animal = {
    name: "Dog"
};

// 프로토타입을 교체함
car.__proto__ = animal;
// K5 출력
console.log(car.name);
// [[Prototype]]을 눌러서 확인하면 안에 name: "Dog" 프로퍼티를 확인할 수 있다.
console.log(car);

🔥 프로토타입 체인으로 인해 K5가 출력된다. car 객체 위에 animal이 상속되어 있는 형태라고 생각하면 편하다. 그래서 car부터 먼저 프로퍼티를 확인하기 때문에 K5가 출력된다. 하지만 [[Prototype]] 안에는 animal의 프로퍼티가 존재한다.
🔥 proto를 코드 내에서 직접 사용하는 것은 권장하지 않으며 접근 방법은 Object 메소드를 사용하면 된다.
🔥 Object.getPrototypeOf와 Object.setPrototypeOf()를 사용하면 된다.
✨ 상속은 class를 사용하는게 더 좋은것 같다. (내 생각)

📌 8-5 proto와 prototype의 차이점

함수객체는 생성자 함수로 사용할 수 있으므로 자체적으로 prototype 프로퍼티를 가진다. 즉 인스턴스의 프로토타입을 가리킨다.

  • proto의 모든 객체에서 가지고 있으며 객체가 자신의 프로토타입에 접근하거나 수정하기 위해서 사용한다.
  • prototype 프로퍼티는 함수 객체에서 가지고 있으며 생성자 함수가 인스턴스를 생성할 때 프로토타입을 할당하기 위해서 사용한다.

📌 8-6 constructor 프로퍼티와 생성자 함수

  • 모든 프로토타입은 constructor 프로퍼티를 갖고 있으며 constructor 프로퍼티는 자신을 참조하는 생성자 함수를 가리킨다.
  • 프로토타입과 생성자 함수는 단독으로 존재할 수 없고 언제나 같이 존재한다.
  • 리터럴 표현식으로 생성해도 동일한 특성을 갖는다.
  • 리터럴 표현식으로 생성하면 생성자 함수 Object, Function, Array 등이 있지만 최종 프로토타입은 Object이다. (생성자 함수로 인스턴스가 생성되기 때문이다. 함수도 객체이다.)
  • 리터럴 표현식으로 생성해도 자바스크립트 엔진이 자동으로 Wrapper 객체처럼 new을 붙혀서 생성하는것 같다. (내 생각)

📌 8-7 프로토타입 체인

객체의 프로퍼티에 접근 할려고 할 때 해당 객체에 프로퍼티가 없으면 [[Prototype]]을 따라서 부모에게 상속받은 것 처럼 프로퍼티를 순차적으로 검색하여 있으면 프로퍼티를 사용한다.

  • 프로토타입 체인은 상속과 프로퍼티를 검색하기 위해 사용한다.

📌 8-8 생성자 함수로 prototype 조작하기

생성자 함수에서 prototype을 조작해서 생성자 함수가 생성하는 인스턴스에 상속이 가능하다.

function Car(name) {
    this.carName = name;
}
// 프로토타입으로 추가
Car.prototype.log = function() {
    console.log(this.carName);
}
// 생성자 함수로 인스턴스 생성
const car = new Car("K5");
// 출력 : K5
car.log();
// prototype 확인해보기
console.dir(car);
// Object 메소드를 프로토타입 체인에 의하여 사용가능
console.log(car.hasOwnProperty("carName"));

🔥 해당과정의 순서를 생각해보면 일단 Car라는 생성자 함수로 인스턴스인 car를 생성한다. 그러면 car라는 객체에 Car의 프로퍼티와 프로토타입이 상속되어 사용하게 된다. 그리고 프로토타입도 객체이기 때문에 Object.prototype를 가지게 된다. 그러므로 Object.prototype도 사용이 가능하다.

📌 8-9 프로토타입을 이용한 상속 구현

ES6 부터는 class의 extends를 이용하여 상속을 구현하지만 프로토타입을 이용해도 상속을 구현할 수 있다.

🧩 Object.create("프로토타입", [프로토타입 옵션])
객체를 생성할 수 있는 방법이다. 프로토타입을 지정해주면 객체가 생성된다.

// 프로토타입을 연결한뒤 key값이 key이며 value값이 value인 요소를 가진 객체를 생성한다.
const obj = Object.create(Object.prototype, {
    key: {
        value: "value"
    }
});
// 결과 : { key: value }
console.log(obj.key);

🧩 프로토타입을 이용해서 상속구현

// A인 함수를 생성
function A() {}
// 생성자 함수로 사용하기 위해 prototype 메소드 생성
A.prototype.logA = function() {
    console.log('A');
}
// A를 상속받을 B 함수를 생성
function B() {}
// B의 프로토타입을 A의 프로토타입을 가진 객체로 지정
B.prototype = Object.create(A.prototype);
// 현재 상태는 B의 constructor가 A를 가리킴 다시 B로 지정
B.prototype.constructor = B;
// B의 prototype 메소드 생성
B.prototype.logB = function() {
    console.log('B');
}

// B를 상속받을 C 함수를 생성
function C() {}
// B가 A를 상속 받는코드와 똑같음
C.prototype = Object.create(B.prototype);
C.prototype.constructor = C;
C.prototype.logC = function() {
    console.log('C');
}
// 인스턴스 생성
const c = new C();
// 결과 : C
c.logC();
// 결과 : B
c.logB();
// 결과 : A
c.logA();

🔥 프로토타입 체인을 따라가 상속받은 메소드들을 찾아서 출력한다.

profile
JS 코린이

0개의 댓글