반응형
소개
- 자바스크립트는 프로토타입 기반 언어이며, 상속을 통한 프로퍼티, 메서드 조회 및 코드 재사용성을 위해 프로토타입을 사용합니다.
- 이번 글에서는 프로토타입과 프로토타입 체인, 프로토타입의(을 통한) 상속에 대해 알아보겠습니다.
프로토타입과 프로토타입 체인
- 자바스크립트에서는 원시타입(numbers, strings, boolean 등)과 참조타입(arrays, object, function) 두가지의 데이터 타입이 있습니다.
- 원시타입과 참조타입 둘 다 각각 object로 감싸여져있습니다.
(Both the primitive and the object types are wrapped by their respective objects.) - 숫자는 `Number`로, 문자열은 `String`로, 부울은 `Boolean`으로 래핑됩니다.
- 배열은 `Array`에 의해, 객체는 `Object`에 의해, 함수는 `Function`에 의해 래핑됩니다.
- 이런 모든 래핑하는 객체에는 prototype이라는 프로퍼티가 있습니다.
- 이 프로토타입은 재사용 가능한 모든 속성, 메서드를 포함하는 객체이며 그것의 부모 프로토타입도 가지고 있습니다.
- 이러한 래핑하는 객체들의 부모는 `Object`라고 불리는 전역 객체입니다.
- 프로토타입들에 의해서 서로 연결된 객체들의 체인은 프로토타입 체인이라고 합니다.
- 예시를 통해 프로토타입 체인을 시각화 해봅시다.
- 이것이 어떻게 코드에서 작동하는지 봅시다.
- 변수의 프로토타입을 얻기위하여 `Object.getPrototypeOf()`메서드를 사용합니다.
const arr = [1, 2, 3];
const arrWrapperProto = Object.getPrototypeOf(arr);
console.log(arrWrapperProto); // Array
const objectProto = Object.getPrototypeOf(arrWrapperProto);
console.log(objectProto); // Object
const objectParentProto = Object.getPrototypeOf(objectProto);
console.log(objectParentProto); // null
프로퍼티, 메소드 조회
- 만약 여러분이 프로퍼티나 메서드에 접근하려고 노력할 때 자바스크립트는 그것들을 맨 먼저 현재 객체에서 찾으려고 할 것입니다.
- 그것들을 현재 객체에서 찾지 못할경우 프로토타입 체인을 이용하여 부모의 객체에서 찾습니다.
- 이 과정을 프로퍼티와 메서드를 발견할 때까지 혹은 null에 도달할 때까지 지속합니다.
- 이것이 바로 속성 또는 메서드를 조회하는 방법입니다.
Object.prototype
모든 객체는 프로토타입의 계층 구조인 프로토타입 체인에 묶여 있다. 자바스크립트 엔진은 객체의 프로퍼티(메서드 포함)에 접근하려고 할 때 해당 객체에 접근하려는 프로퍼티가 없다면 __proto__ 접근자 프로퍼티가 가리키는 참조를 따라 자신의 부모 역할을 하는 프로토타입의 프로퍼티를 순차적으로 검색한다. 프로토타입 체인의 종점, 즉 프로토타입 체인의 최상위 객체는 Object.prototype이며, 기 객체의 프로퍼티와 메서드는 모든 객체에 상속된다.
출처 : 모던 자바스크립트 Deep Dive
프로토타입의(을 통한) 상속
- 프로토타입의 주용 사용 사례는 코드를 상속받아 재사용하는 것입니다.
- 상속은 프로토타입 체인으로 가능하게 됩니다.
- 이해를 위한 예를 살펴봅시다.
const person = {
isTalkative: true,
talk() {
console.log("Talking...");
},
};
const student = {
name: "John",
age: 12,
};
Object.setPrototypeOf(student, person);
console.log(student.name); // John
console.log(student.isTalkative); // true
student.talk(); // Talking...
console.log(Object.getPrototypeOf(student) === person); // true
- 여기서 우리는 `Object.setPrototypeof()`메서드를 사용하여 student의 프로토타입을 person으로 지정하였습니다.
- 이말은 곧 student는 상속을 통해 person의 프로퍼티와 메서드를 상속받게 됬다는 것입니다.
- student는 person의 모든 프로퍼티와 메서드에 접근이 가능하게 된 것입니다.
- 위의 예시에서 프로토타입 체인을 시각화해봅시다.
- student의 프로토타입은 person이고, person의 프로토타입은 `Object`입니다. 그리고 `Object`의 프로토타입은 `null`입니다.
- 이것은 곧 student는 `Object`와 person의 프로퍼티들과 메서드들에 접근할 수 있을 것이라는 것을 의미합니다.
- 비슷하게 person역시 `Object`의 모든 프로퍼티와 메서드에 접근 할 수 있을 것 입니다.
객체 생성
- 프로토타입에 대하여 알아보았으니 프로토타입을 이용해서 우리 자신의 객체를 만드는 방법을 알아봅시다.
function Student(name, age) {
this.name = name;
this.age = age;
}
Student.prototype.isTalkative = true;
Student.prototype.talk = function () {
console.log("Talking...");
};
const john = new Student("John", 12);
console.log(john.age); // 12
john.talk(); // Talking...
- 위 예시에서 Student 함수는 객체를 만드는 생성자 함수(constructor function)입니다.
- 관례적으로 생성자 함수는 일반함수와 구분하기 위하여 첫글자를 대문자로 적어줍니다.
- `this`키워드는 생성자 함수로 인해 만들어질 인스턴스를 가르킵니다.
- 화살표 함수의 경우 생성자 함수로서 사용될 수 없음을 기억해주십시오.
- `new`키워드는 생성자 함수로 객체를 생성할 때 사용합니다.
- `Object.create()` 메서드는 object literals로 부터 새로운 객체를 만들 때 사용됩니다.
- 예시를 통해 확인해봅시다.
const person = {
isHappy: true,
introduce() {
console.log(`Hi I'm ${this.name}`);
},
};
const john = Object.create(person);
john.name = "John";
console.log(john.isHappy); // true
john.introduce(); // Hi I'm John
console.log(Object.getPrototypeOf(john) === person); // true
- `Object.create()` 메서드는 john의 프로토타입을 person 객체로 설정하였습니다.
- ES6에서 자바스크립트에서 클래스가 추가되었지만 자바스크립트가 클래스기반 언어임을 나타내는 것은 아닙니다. 단순히 문법적으로 바뀐 것일 뿐 여전히 프로토타입 기반의 상속을 사용하고 있습니다.
결론
- 프로토타입은 객체이고 이 객체는 그것들의 부모 프로토타입과 함께 모든 재사용 가능한 프로퍼티들과 메서드를 포함하고 있습니다.
- 프로토타입 체인은 프로토타입들에 의해 연결된 체인입니다.
- 자바스크립트는 프로퍼티와 메서드를 찾을 때 프로퍼티 체인을 사용합니다.
- 프로토타입을 통한 상속은 프로토타입 체인을 통해 부모 객체의 프로퍼티와 메서드들을 재사용하게 해줍니다.
출처 : https://dev.to/mvganeshkumar06/prototypes-in-javascript-40md
반응형
'JavaScript' 카테고리의 다른 글
Detail of prototype in Javascript (0) | 2021.10.06 |
---|---|
[번역] Introduction to Promises in JavaScript 자바스크립트에서의 promise 소개 (0) | 2021.09.18 |
모든 자바스크립트 파일을 브라우저에서 한 번에 로딩 할 때의 문제점과 그 해결([번역]How to load JavaScript properly) (1) | 2021.09.13 |
기존 자바스크립트와 ES6의 차이점 및 특징 (1) | 2021.09.11 |
[요약] What the heck is the event loop anyway? 이벤트 루프란 무엇인가? (0) | 2021.09.04 |