[FE] 📚 프로토타입 체인이란?
🤗 오늘의 위클리 페이퍼는
프로토타입 체인에 대해 알아보는 토픽입니다.
📝 프로토타입란?
프로토타입(Prototype)이란 단어는 원형이라는 의미를 가지고 있습니다.
자바스크립트에서 프로토타입은 객체의 원형이라 할 수 있습니다.
모든 객체들은 메소드와 속성들을 상속 받기 위해 프로토타입 객체를 가집니다.
주어진 객체의 모든 속성을 콘솔에서 볼 수 있는 console.dir() 메소드를 활용하면,
[[Prototype]] 이라는 숨어있는 속성을 확인할 수 있습니다.
[[Prototype]] 은 해당 객체의 입장에서 자신의 부모 역할을 하는 객체를 가리킵니다
📗 자바스크립트의 프로토타입
자바스크립트는 객체 지향 언어입니다. 객체 지향 언어에서 상속은 중요한 개념인데,
자바스크립트는 이를 프로토타입 체인이라는 독특한 방식으로 구현합니다.
모든 자바스크립트 객체는 다른 객체로부터 상속을 받을 수 있습니다.
이 상속을 가능하게 하는 것이 바로 프로토타입 입니다.
모든 객체는 숨겨진 프로토타입 객체에 연결되며, 이 프로토타입 객체를 통해
다른 객체의 속성과 메서드를 상속 받습니다.
[[Prototype]] 은 개발자가 직접 접근이 불가하고 간접적으로 접근할 수 있는 내부 슬롯입니다. 내부 슬롯이란 자바스크립트 엔진의 구현된 내용을 설명하기 위한 pseudo 프로퍼티를 말합니다. 직접 접근을 불가하게 해서 프로토타입 체인의 방향을 자식에서 부모를 탐색하는 단방향으로 지키고, 개발자의 실수로 순환참조하는 일이 없도록 합니다.
function Person(name) {
this.name = name;
}
console.dir(Person);
__proto__ 는 객체의 프로토타입([[Prototype]])을 접근하기 위한 프로퍼티입니다. 이를 통해 자신의 프로토타입에 접근할 수 있습니다. Object.getPrototypeOf() 와 동일한 기능을 수행합니다.
function Person(name) {
this.name = name;
}
console.log(Person.__proto__ === Object.getPrototypeOf(Person)); // true
prototype 프로퍼티는 생성자 함수로 호출할 수 있는 객체, 즉 constructor 를 소유하는 프로퍼티입니다. Person() 생성자 함수로 foo 를 만들었다면, foo 객체를 생성한 객체는 Person() 생성자 함수입니다. 따라서 foo 객체의 프로토타입 객체는 Person() 의 생성자 함수, Person.prototype 입니다. 일반 객체와 생성자 함수로 호출할 수 없는 arrow function은 prototype 프로퍼티가 없습니다.
function Person(name) {
this.name = name;
}
const foo = new Person('코드잇');
console.log(foo.__proto__ === Person.prototype); // true
console.log(Person.prototype) // {constructor: f}
📙 프로토타입 체인
프로토타입 체인은 객체가 다른 객체로부터 속성과 메서드를 상속받는 메커니즘입니다.
객체는 자신의 속성이나 메서드가 없을 때, 프로토 타입 체인을 따라서 자신의 프로토타입 객체를 검색합니다.
이 과정은 최상위 프로토타입 객체인 `object.prototype'에 도달할 때까지 계속됩니다.
자바스크립트는 특정 객체의 프로퍼티나 메소드에 접근하려고 할 때 해당 객체에 접근하려는 프로퍼티나 메소드가 없다면 프로토타입([[Prototype]])이 가리키는 링크를 따라 자신의 부모 역할을 하는 프로토타입 객체의 프로퍼티나 메소드를 차례대로 검색합니다. 프로토타입 링크를 따라 계속해서 상위 프로토타입을 검색할 수 있고, 이러한 프로토타입 간의 연결을 프로토타입 체인이라고 합니다. 프로토타입을 계속해서 타고가면 자바스크립트의 모든 객체는 Object.prototype 에 최종 도착합니다.
function Person(name) {
this.name = name;
}
const foo = new Person('테스터');
const string = 'abc';
const number = 123;
const array = [1,2,3];
const arrowFunction = () => 'arrowFunction';
const object = {a: 'abc'};
console.log(foo.__proto__ === Person.prototype); // true
console.log(string.__proto__ === String.prototype); // true
console.log(number.__proto__ === Number.prototype); // true
console.log(array.__proto__ === Array.prototype); // true
console.log(arrowFunction.__proto__ === Function.prototype); // true
console.log(foo.__proto__.__proto__ === Object.prototype); // true
console.log(string.__proto__.__proto__ === Object.prototype); // true
console.log(number.__proto__.__proto__ === Object.prototype); // true
console.log(array.__proto__.__proto__ === Object.prototype); // true
console.log(arrowFunction.__proto__.__proto__ === Object.prototype); // true
console.log(object.__proto__ === Object.prototype); // true
✅ 요약
프로토타입 체인은 코드의 재사용성을 높이고, 메모리 효율성을 향상시킵니다. 공통 메서드를 프로토타입에 정의하면, 모든 인스턴스가 이를 공유하여 사용할 수 있습니다.
프로토타입 체인을 지나치게 깊게 구성하면 성능 문제가 발생할 수 있습니다. 따라서 상속을 설계할 때는 이를 고려하여 적절한 깊이로 유지하는 것이 좋습니다.
프로토타입 체인은 자바스크립트의 강력한 특징 중 하나로, 객체 지향 프로그래밍을 효율적으로 구현할 수 있게 해줍니다. 프로토타입 체인의 개념을 잘 이해하면, 자바스크립트로 보다 효율적이고 재사용 가능한 코드를 작성할 수 있습니다. 이번 글이 프로토타입 체인을 이해하는 데 도움이 되었기를 바랍니다.