특징이나 성질을 나타내는 속성
이 속성 중 필요한 속성만 간추리면, 추상화
속성을 통해 여러 개의 값을 하나의 단위로 구성한 복합적인 자료구조 -> 객체
= 상태를 나타내는 데이터 + 조작할 수 있는 동작
상속이란?
어떤 객체의 프로퍼티 또는 메서드를 다른 객체가 상속받아 그대로 사용할 수 있는 것
자바스크립트는 프로토타입을 기반으로 상속을 구현하여 불필요한 중복 제거
예를 들면, 현대자동차임
자동차 설계도가 있고,
이 설계도로 자동차를 찍어냄 -> 인스턴스
현대자동차는 좋은 차량용 소프트웨어를 가지고 있음
그런데 굳이 생산하는 차량 대당 소프트웨어를 만들 필요는 없음
중앙의 서버를 공유하면 됨
"그러나 생성자 함수로 인스턴스를 생성하면, 차마다 소프트웨어를 만들게 됨"
굳이?
하지만 상속을 통해 불필요한 중복 제거
-> 차마다 각자의 소프트웨어를 만들 필요가 없음
프로토타입 객체란, 객체지향 프로그래밍의 근간을 이루는 객체 간 상속을 구현하기 위해 사용
어떤 객체의 상위 객체로서, 다른 객체에 공유 프로퍼티(메서드 포함)를 제공
➡️ 프로토타입을 상속 받은 하위(자식) 객체는 상위 객체의 프로퍼티를 자신의 프로퍼티처럼 자유롭게 사용 가능
__proto__ 접근자 프로퍼티__proto__는 접근자 프로퍼티[[Prototype]] 내부 슬롯에 직접 접근할 수 없고,
__proto__ 접근자 프로퍼티를 통해 간접적으로 [[Prototype]] 내부 슬롯의 값, 즉 프로토타입에 접근 가능
__proto__ 접근자 프로퍼티는 상속을 통해 사용됨__proto__ 접근자 프로퍼티는 객체가 직접 소유하는 프로퍼티가 아니라 Object.prototype의 프로퍼티
➡️ 모든 객체는 상속을 통해 Object.prototype.__proto__ 접근자 프로퍼티 사용 가능
__proto__ 접근자 프로퍼티를 통해 프로토타입에 접근하는 이유상호 참조에 의해 프로토타입 체인이 생성되는 걸 방지하기 위해서
프로토타입 체인은 단방향 링크드리스트로 구현되어야 함
따라서, 순환 참조하는 프로토타입 체인이 만들어지면, 프로토타입 체인 종점이 존재하지 않고,
프로토타입 체인에서 프퍼티를 검색할 때 무한루프에 빠짐
__proto__ 접근자 프로퍼티를 코드 내에서 직접 사용하는 것은 권장하지 않는다.모든 객체가 __proto__ 접근자 프로퍼티를 사용할 수 있는 것은 아님
따라서 __proto__ 접근자 프로퍼티 대신 프로토타입의 참조를 취득하고 싶은 경우 get/set 메서드를 사용
함수 객체만이 소유하는 prototype 프로퍼티는 생성자 함수가 생성할 인스턴스의 프로토타입을 가리킴
따라서, 생성자 함수로서 호출할 수 없는 함수, non-constructor인 화살표 함수와 ES6 메서드 축약 표현으로 정의한 메서드는 prototype 프로퍼티를 소유하지 않으며 프로토타입도 생성하지 않음
모든 객체가 가지고 있는 (엄밀히, Object.prototype으로부터 상속받은) __proto__ 접근자 프로퍼티와,
함수 객체만이 가지고 있는 prototype 프로퍼티는 결국 동일한 프로토타입을 가리킴
그러나 사용하는 주체가 다르다
__proto__ 접근자 프로퍼티 : 모든 객체
prototype 프로퍼티 : 생성자 함수
모든 프로토타입은 constructor 프로퍼티를 가짐
constructor 프로퍼티는 prototype 프로퍼티로 자신을 참조하고 있는 생성자 함수를 가리킴
이 연결은, 생성자 함수가 생성될 때 (즉 함수 객체가 생성될 때)이뤄짐
생성자 함수에 의해 생성된 인스턴스는, 위에 설명한 것처럼 생성자 함수와 연결됨
이때 constructor 프로퍼티가 가리키는 생성자 함수는, 인스턴스를 생성한 생성자 함수
리터럴 표기법에 의한 객체 생성 방식은, new 연산자를 사용하지 않기도 한다.
물론 이때도 프로토타입이 존재하지만,
리터럴 표기법에 의해 생성된 객체의 경우 프로토타입의 constructor 프로퍼티가 가리키는 생성자 함수가 반드시 객체를 생성한 생성자 함수라고 단정 불가
객체 리터럴이 평가될 때는 추상 연산 OrdinaryObjectCreate를 호출하여 빈 객체를 생성하고 프로퍼티를 추가
따라서 생성자 함수 호출과는 세부 내용이 다름
하지만 큰 틀에서,
리터럴 표기법으로 생성한 객체도 생성자 함수로 생성한 객체와 본질적인 면에서 큰 차이가 없음
리터럴 표기법에 의해 생성된 객체도 생성자 함수와 연결은 되어 있음
즉, 모든 객체는 생성자 함수와 연결되어 있음
프로토타입은 생성자 함수가 생성되는 시점에 더불어 생성
객체는 여러 가지 방법으로 생성되지만,
추상 연산 OrdinaryObjectCreate에 의해 생성된다는 공통점이 있음
프로토타입은 이 추상 연산 OrdinaryObjectCreate에 전달되는 인수에 의해 결정됨
자바스크립트는 객체의 프로퍼티와 메서드에 접근하려고 할 때,
해당 객체에 접근하려는 프로퍼티가 없다면 [[Prototype]] 내부 슬롯의 참조를 따라 자신의 부모 역할을 하는 프로토타입의 프로퍼티를 순차적으로 검색
➡️ 프로토타입 체인
프로토타입 프로퍼티와 같은 이름의 프로퍼티를 인스턴스에 추가하면,
프로토타입 체인을 따라 프로토타입 프로퍼티를 검색하여 프로토타입 프로퍼티를 덮어 쓰는 게 아니라
인스턴스 프로퍼티로 추가
이처럼 상속 관계에 의해 프로퍼티가 가려지는 현상
= 프로퍼티 섀도잉
프로토타입은 임의의 다른 객체로 변경
부모 객체인 프로토타입을 동적으로 변경 가능하다는 것
-> 객체 간의 상속 관계를 동적으로 변경 가능
우변의 생성자 함수의 prototype에 바인딩된 객체가 좌변의 객체의 프로토타입 체인 상에 존재하면 true,
그렇지 않은 경우 false로 평가
__proto__에 의한 직접 상속생성자 함수로 인스턴스를 생성하지 않아도 참조/호출할 수 있는 프로퍼티/메서드