자바스크립트는 명령형, 함수형, 프로토타입 기반, 객체지향 프로그래밍을 지원하는 멀티 패러다임 언어다.
--> 프로토타입 기반의 객체지향 프로그래밍 언어이다!
추가적으로 객체지향 프로그래밍에 대해서는 해당 이름의 포스트를 참고하길 바란다.
프로토타입의 참조를 취득하고 싶다면?
함수 객체만이 소유하는 prototype 프로퍼티는 생성자 함수가 생성할 인스턴스의 프로토타입을 가리킨다.
처음에는 위의 말이 이해가 가지 않았다. 하지만 몇번씩 관련 내용을 찾아보니 이해가 갔다.
- prototype 프로퍼티는 생성자 함수가 생성할 객체(인스턴스)의 프로토타입을 가리킨다.
- 따라서 non-constructor인 화살표 함수와 ES6 메서드 축약 표현으로 정의한 메서드는 prototype 프로퍼티를 소유하지 않고 프로토타입도 생성하지 않는다.
- 일반 함수(함수선언문과 표현식)도 prototype 프로퍼티를 소유하지만 객체를 생성하지 않기에 아무런 의미가 없다.
__proto__ 접근자 프로퍼티와 prototype 프로퍼티 비교
구분 | 소유 | 값 | 사용주체 | 사용목적 |
---|---|---|---|---|
__proto__ 접근자 프로퍼티 | 모든객체 | 프로토타입 참조 | 모든객체 | 자신의 프로토타입에 접근 또는 교체 |
prototype 프로퍼티 | constructor | 프로토타입 참조 | 생성자 함수 | 생성할 인스턴스의 프로토타입을 할당하기 위해 사용 |
//생성자 함수
function Person(name){
this.name=name;
}
//me 인스턴스 생성
const me = new Person("Lee");
//1번그림 -
console.log(Person.prototype === me.__proto__); //true
//2번그림
console.log(me.constructor=== Person); //true
그림으로 이해해 보자
1번 그림
2번 그림
모든 프로토타입은 constructor 프로퍼티를 가짐
이 constructor 프로퍼티는 prototype 프로퍼티로 자신을 참조하고 있는 생성자 함수를 가리킴
즉, me 객체는 프로토타입의 constructor 프로퍼티를 통해 생성자 함수인 Person과 연결되는 것이다.
me 객체엔 constructor 프로퍼티 가 없지만 me 객체의 프로토타입인 Person.prototype의 constructor 프로퍼티를 상속받아 사용할 수 있는 것이다.
이를 보면 프로토타입과 생성자 함수는 언제나 쌍으로 존재한다!
프로토타입 체인은 프로토타입이 단방향 링크드 리스트 형태로 연결되어 있는 상속 구조를 말한다.
객체의 프로퍼티나 메서드에 접근하려고 할 때 해당 객체에 접근하려는 프로퍼티 또는 메서드가 없다면 프로토타입 체인을 따라 프로토타입의 프로퍼티나 메서드를 차례대로 검색한다.
function Person(name){
this.name = name;
}
//프로토타입 메서드
Person.prototype.sayHi = function(){
console.log(`Hi ${this.name}`);
};
const me = new Person("Joe");
// hasOwnProperty 는 Object.prototype 메서드임
console.log(me.hasOwnProperty("name")); // true
console.log(Object.getPrototypeOf(me)===Person.prototype); //true
console.log(Object.getPrototypeOf(Person.prototype) === Object.prototype); //true
이 내용을 공부하고 이해함으로써 왜 mdn에 나와있는 각각의 메서드들에 prototype이 붙어있는지, 왜 바로 사용할 수 있는지 알게 되었다.
(ex : Array.prototype.reduce() 메서드등..)
물론 완벽하진 않지만 위 내용을 수정해 나가며 더 알아 보아야겠다.