1. 객체지향 프로그래밍
- 독립적인 단위, 즉 객체의 집합으로 프로그램을 표현하려는 프로그래밍 패러다임
- 속성을 통해 실체를 인식하거나 구별할 수 있다.
- 상태 데이터와 상태 데이터를 조작할 수 있는 동작을 하나의 논리적 단위로 묶어 생각한다.
객체 : 속성을 통해 여러 개의 값을 하나의 단위로 구성한 복합적인 자료구조
프로퍼티 : 객체의 상태 데이터
메서드 : 객체의 동작
추상화 : 다양한 속성 중에서 프로그램에 필요한 속성만 간추려내어 표현하는 것
2. 상속과 프로토타입
상속 : 어떤 객체의 프로퍼티나 메서드를 다른 객체가 상속받아 그대로 사용할 수 있는 것을 의미한다.
=> 자바스크립트는 프로토타입을 기반으로 상속을 구현하여 불필요한 중복을 제거할 수 있다.
=> 상속은 코드의 재사용 관점에서 매우 유용하다.
생성자 함수가 생성할 모든 인스턴스가 공통적으로 사용할 프로퍼티나 메서드를 미리 구현해두면 ...
생성자 함수가 생성할 모든 인스턴스는 별도의 구현없이 상위 객체인 프로토타입의 자산을 공유하여 사용할 수 있다.
모든 객체는 하나의 프로토타입을 가지고 모든 프로토타입은 생성자 함수와 연결이 되어있다.
내부 슬로셍는 직접 접근할 수 없지만 __proto__ 접근자 프로퍼티를 통해 간접적으로 접근할 수 있다.
프로토타입은 자신의 constructor 프로퍼티를 통해 생성자 함수에 접근할 수 있고
생성자 함수는 자신의 prototype 프로퍼티를 통해 프로토타입에 접근할 수 있다.
3. __proto__접근자 프로퍼티
- 모든 객체는 __proto__ 접근자 프로퍼티를 통해 자신의 프로토타입, 즉 [[prototype]] 내부 슬롯에 간접적으로 접근할 수 있다.
- __proto__ 접근자 프로퍼티는 상속을 통해 사용된다.
- 객체가 직접 소유하는 프로퍼티가 아니라 Object.prototype 의 프로퍼티이다.
- 모든 객체는 상속을 통해 Object.prototype__proto__접근자 프로퍼티를 사용할 수 있음
🤔 그렇다면 __proto__접근자 프로퍼티를 통해 프로토타입에 접근하는 이유가 무엇일까?
상호 참조에 의해 포로토타입 체인이 생성되는 것을 방지하기 위해서이다!
=> 단방향 링크드 리스트로 구현되어야 한다.
=> 한쪽 방향으로만 흘러가야함..
* 모든 프로토타입은 constructor 프로퍼티를 가진다.
* 이 constructor 프로퍼티는 Prototype 프로퍼티로 자신을 참조하고 있는 생성자 함수를 가리킨다.
따라서.. 이연결은 생성자 함수가 생성될 때.. 즉 함수객체가 생성될 때 이루어진다.
4. 프로토타입 생성 시점
=> 프로토타입은 생성자 함수가 생성되는 시점에 더불어 생성됨
- 사용자 정의 생성자 함수 : constructor 는 함수 정의가 평가되어 함수 객체를 생성하는 시점에 프로토타입도 더불어 생성
- 빌트인 생성자 함수 : 빌트인 생성자 함수가 생성되는 시점에 프로토타입도 더불어 생성
5. 프로토타입 체인
- 객체에 어떤 프로퍼티나 메서드를 요청할 때, 자바스크립트 엔진은 먼저 그 객체 안에 해당 프로퍼티나 메서드가 존재하는지 찾는다.
- 만약 존재하지 않으면, 그 객체의 프로토타입에서 다시 찾는다.
- 프로토타입 체인은 계속해서 상위 프로토타입으로 이어지며, 최종적으로 Object.prototype에서 체인이 끝난다.
- Object.prototype은 모든 객체의 최상위 프로토타입으로,체인의 종점이라고 부른다.
- 여기까지 도달했음에도 원하는 속성을 찾지 못하면 undefined를 반환다
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name}`);
};
const person1 = new Person('hihilong');
person1.sayHello(); // Hello, my name is hihilong
🤔 우리 전에 배웠던 스코프 체인이란는 것도 있었다!
- 프로토타입 체인은 객체의 프로퍼티와 메서드를 상속받기 위한 메커니즘으로, 객체 간의 관계를 설정하는 것이다.
- 스코프 체인은 함수와 변수의 유효 범위를 결정하며, 코드 실행 중 식별자를 찾는 데 사용된다.
- 두 체인 모두 체인 구조를 통해 상위 단계로 이동하며 필요한 것을 찾지만,
- 프로토타입 체인은 객체의 프로퍼티와 메서드를, 스코프 체인은 변수와 함수의 식별자를 찾는 데 사용된다.
- 서로 연관없이 작동하는 것이 아니라 협력하여 식별자와 프로퍼티를 검색하는데 사용된다.
6. 오버라이딩과 프로퍼티 섀도잉
프로토타입 프로퍼티와 같은 이름의 프로퍼티를 인스턴스에 추가하면 프로토타입 체인을 따라 ㅍ로토타입 프로퍼티를 검색하여 프로토타입 프로퍼티를 덮어쓰는 것이 아니라 인스터스 프로퍼티로 추가한다.
이때 인스턴스 메서드는 프로퍼ㅗ타입 메서드를 오버라이딩 했고 프로토타입 메서드는 가려진다.
오버라이딩은 상속받은 메서드나 속성을 재정의하는 것을 의미한다.
자식 객체(또는 클래스)가 부모 객체로부터 상속받은 메서드나 속성을 자신의 필요에 맞게 변경할 수 있는데.
이를 통해 같은 이름의 메서드나 속성이 상속된 경우, 자식 객체는 해당 메서드나 속성의 재정의된 버전을 사용한다.
어떻게 동작하는데 ?
- 자바스크립트에서는 프로토타입 체인을 통해 상위 객체(부모 객체)에서 메서드나 속성을 상속받는다.
- 자식 객체는 같은 이름의 메서드나 속성을 가질 수 있으며, 자식 객체에서 먼저 정의된 메서드나 속성이 있으면 상속받은 메서드나 속성을 오버라이드한다.
- 상속된 메서드나 속성은 덮어쓰기가 되지만, 부모 객체의 프로토타입에 여전히 존재.
프로퍼티 셰도잉은 자식 객체의 속성이나 메서드가 부모 객체로부터 상속받은 속성이나 메서드와 동일한 이름을 가질 때 발생하는 현상을 말한다. 이 경우, 자식 객체에서 해당 속성을 참조할 때 상속된 부모 객체의 속성이나 메서드가 "가려지게(셰도잉)" 되는 것이다.
어떻게 동작하는데 ?
- 프로퍼티 셰도잉은 객체 내부의 속성과 프로토타입 체인의 상위 객체에 있는 동일한 이름의 속성이나 메서드가 겹칠 때 발생한다.
- 자바스크립트는 객체에서 먼저 속성이나 메서드를 찾기 때문에, 자식 객체의 속성이 부모 객체의 동일한 속성을 가리게 된다
- 셰도잉된 부모 객체의 속성이나 메서드는 여전히 존재하지만, 자식 객체에서 직접적으로 접근할 수 없다.
7. 프로토타입의 교체
- 생성자 함수에 의한 교체
- constructor 프로퍼티와 생성자 함수 간의 연결이 끊긴다.
- 인스턴스에 의한 교체
- __proto__ 접근자 프로퍼티를 통해 교체하는 것은 이미 생성된 객체의 프로토타입을 교체하는 것이다.
8. 프로퍼티 존재 확인
- In 연산자 : 특정 프로퍼티가 존재하는지의 여부 확인
- 혹은 Reflect.has 메서드 사용= in 연산자와 동일하게 동작함
- Object.prototype.hasOwnproterty메서드 사용하여 특정 프로퍼티 존재하는지 확인할 수 있음
const person = {
name:"hihilong",
addrewss:"Seoul",
};
console.log('name' in person);
//true
9. 프로퍼티 열거
- for 문 : 객체의 모든 프로퍼티를 순회하며 열거하려면 for-in 문
- 객체의 프로퍼티 개수만큼 순회하며 선언한 변수에 프로퍼티를 할당함
- 상속받은 프로포타입의 프로퍼티까지 열거함
- 존재하는 모든 프로토타입의 프로퍼티 중에서 프로퍼티 어트리뷰트의 값이 true 인 프로퍼티를 순회하여 열거함
- for - of
- Array.prototype.forEach 메서드 사용
const arr = [1,2,3];
arr.x = 10;
for (const i in arr) {
console.log(arr[i]);
//1 2 3
}
'Deep Dive 정리' 카테고리의 다른 글
[JS Deep Dive] 22장 - this (0) | 2024.09.19 |
---|---|
[JS Deep Dive] 20장 - strict mode (1) | 2024.09.11 |
[JS Deep Dive] 21장 - 빌트인객체 (0) | 2024.09.10 |
[JS Deep Dive] 18장 - 함수와 일급객체 (0) | 2024.09.04 |
[JS] this 조금 더 정리하기 (0) | 2024.09.04 |