[JavaScript] 프로토타입(Prototype), 클래스(Class)
01. 프로토타입
1.1 프로토타입이란
객체지향 프로그래밍의 중요한 개념 중 하나이다. 동일한 타입의 객체이지만 속성 또는 메소드가 조금씩 다른 객체를 생성하는 경우 프로토타입을 사용하지 않으면 각각의 객체들이 속성, 메소드를 개별생성, 개별소유 한다.
이렇게 될 경우 중복된 코드가 발생하고 메모리의 낭비, 퍼포먼스 저하 등이 발생할 수 있다.
자바스크립트에서는 이를 방지하기 위해 Prototype 이라는 것이 존재한다.
생성자함수의 Prototype을 정해주게 되면 동일한 속성, 메서드를 각각의 객체들이 참조하게 할 수 있게 된다.
1.2 객체의 프로토타입에 접근, 변경 하기
1.2.1 __proto__ 접근자 프로퍼티를 통해 접근하기
객체의 프토토타입에 직접 접근할 수는 없지만 __proto__ 접근자 메서드를 통해서 간접적으로 접근, 할당 해줄 수 있다.
그러나 __proto__
접근자 프로퍼티로 접근하는 방식은 권장하지 않는다.
그 이유는 Object.create(null)
를 통해 프로토타입이 null
인 객체를 생성하게 되면 __proto__
프로퍼티가 아예 존재하지 않기 때문이다. 이것은 정확히 프로토타입에 접근한 것이 아니다
그러나 Object.getPrototypeOf()
를 통해 접근하게 되면 null
이라는 정확한 값을 반환해줄 수 있다.
proto
접근자 메서드는 객체 자신이 소유하고 있는 것이 아니라 최상위의 Object.prototype이 소유하고 있는 것을 참조하는 것일 뿐이기 때문에 프로토타입이 'null'인 객체를 생성하게되면proto
라는 접근자 메서드에 아예 접근을 할 수 없게 되는 것이다.
1.2.2 Object.getPrototypeOf() 를 통해 접근하기
1.2.3 Object.setPrototypeOf() 를 통해 프로토타입 교체, 할당하기
// 빈객체 a 와 프로퍼티를 가지고 있는 b 라는 객체를 만들어 보겠다.
const a = {};
const b = {x : 10};
// a 의 prototype을 b로 변경하겠다.
Object.setPrototypeOf(a, b);
// a 에는 분명 아무것도 들어있지 않지만 prototype을 통해 b 라는 객체를 프로토타입으로 가짐으로써 접근할 수 있게 된다.
console.log(a, Object.getPrototypeOf(a)) // {} { x : 10 }
1.3 객체 생성방식에 따른 차이
객체의 생성방식에 따른 차이가 존재하는데 3가지의 대해서 설명하려고 한다.
1.3.1 Object 생성자 함수
- 자바스크립트 엔진의 추상연산을 통해 빈 객체를 생성하고 인수를 전달하게 된다.
- 추상연산의 OrdinaryObjectCreate에 전달되는 인수로
Object.prototype
을 전달한다. - Object 생성자 함수에 의해 생성된 객체의 경우 Object.prototype을 프로토타입으로 가진다.
1.3.2 객체리터럴 방식
- 추상연산의 OrdinaryObjectCreate에 전달되는 인수로
Object.prototype
을 전달한다. - 객체리터럴에 의해 생성된 객체의 경우 Object.prototype을 프로토타입으로 가진다.
Object생성자함수, 객체리터럴 방식의 차이 빈 객체를 생성하는것은 동일하지만 객체 리터럴의 경우 리터널내부에 프로퍼티를 선언하며 Obejct 생성자 함수의 경우 new 연산자를 통해 인스턴스를 생성 후 프로퍼티를 추가해 준다.
1.3.3 사용자 정의 생성자 함수
- 사용자 정의 함수는 프로토타입이라는 프로퍼티를 가지고 있다.
- 프로토타입의 constructor는 생성자 함수를 가리키고 있다.
- 생성된 객체는 사용자 정의함수와 동일한 프로토타입을 가리키고 있다.
- 즉 사용자 정의함수에 의해 생성된 객체의 프로토타입은 객체를 생성한 함수의 프로토타입을 따른다.
02. 클래스
<작성중>