[JS] 프로토타입
▶ 프로토타입 기반 언어
- js는 프로토타입 기반의 언어라고 불린다.
- 모든 객체들은 프로토타입으로부터 프로퍼티와 메서드를 상속받는다.
콘솔창에서 배열을 만들고 확인해보면 arr배열의 프로토타입은 Array 객체라는 것을 확인할 수 있다.
즉 arr 배열이 Array 객체의 프로퍼티와 메서드를 상속받아 사용할 수 있는 것이다. 이때, Array 객체를 arr 배열의 프로토타입이라고 한다.
아래의 코드에서 push()함수와 length 프로퍼티를 사용할 수 있는 이유는 arr 배열이 프로토타입 Array 객체의 push()함수와 length 프로퍼티를 상속받기 때문이였다는 것을 확인할 수 있다!
const arr = [1, 2, 3];
arr.push(4);
console.log(arr.length);
배열 뿐만 아니라 숫자형은 Number라는 객체, 문자열은 String이라는 객체 등 js의 데이터 유형은 각자 프로토타입 객체를 가지고 있다.
▶ 프로토타입이란?
prototype은 일종의 유전자 같은 개념이다.
함수와 프로퍼티가 상속된다는 것은 특정 객체가 push(), pop() 함수와 length 프로퍼티를 가지고 있다는 것을 의미한다. 여기서 말하는 특정 객체를 프로토타입(Prototype)이라고 한다.
프로토타입은 상위 객체를 의미한다.
JavaScript의 모든 객체(배열, 객체, 함수 등)는 상위 객체를 참조하며, 이 상위 객체를 프로토타입이라고 말한다.
아래의 코드는 생성자 함수를 통해 상속을 구현한 것이다. score라는 부모가 가지고 있는 속성 math와 eng를 자식인 obj에게 물려주었다.
function score() {
this.math = 86;
this.eng = 94;
}
const obj = new score();
console.log(obj);
이와 비슷하게 prototype을 사용하면 부모의 속성을 자식 object에게 데이터 물려줄 수 있다.
function score() {
this.math = 86;
this.eng = 94;
}
score.prototype.subject = "science";
const obj = new score();
console.log(obj.subject);
위와 같이 prototype에 부모 유전자에 데이터가 기록되어 있으면 자식들이 사용이 가능하다.
▷ 프로토타입 메서드
생성자 함수를 정의할 때 프로퍼티는 함수 안에 정의하고, 메서드는 프로토타입을 사용하여 함수 밖에 정의 하는 것이 일반적이다
- 함수 안에 프로퍼티와 메서드를 함께 정의한다면 중간에 새로운 함수가 필요하거나 기존 함수를 수정해야 할 때 생성자 함수 자체를 수정해야한다.
function User(name, age) {
this.name = name;
this.age = age;
this.addAge = function (user) {
this.age += 1;
console.log(`${user.name}님 주름이 하나 늘었네요(;´༎ຶД༎ຶ)`);
};
}
const user1 = new User("sieun", 22);
console.log(user1.age); // 22
user1.addAge(user1); // sieun님 주름이 하나 늘었네요(;´༎ຶД༎ຶ)
- 따라서 객체의 메서드는 프로토타입을 사용하여 함수 밖에 정의한다.
function User(name, age) {
this.name = name;
this.age = age;
}
// 프로토타입 메서드
User.prototype.addAge = function (user) {
this.age += 1;
console.log(`${user.name}님 주름이 하나 늘었네요(;´༎ຶД༎ຶ)`);
};
const user1 = new User("sieun", 22);
console.log(user1.age); // 22
user1.addAge(user1); // sieun님 주름이 하나 늘었네요(;´༎ຶД༎ຶ)
▷ prototype vs proto
객체의 프로토타입을 확인할때는 proto프로퍼티를 사용하고, 생성자 함수의 프로토타입을 확인할 때는 prototype 프로퍼티를 사용한다.
proto프로퍼티 같은 경우 모든객체가 가지고 있기 때문에 자신에게 연결된 부모 프로토타입 객체를 확인할 수 있다.
person2.__proto__;
prototype 프로퍼티는 생성자 함수에서 사용하는데, 어떤 생성자 함수를 사용했는지, 어떤 프로퍼티와 메서드를 가지는지 등의 정보를 확인할 때 사용한다.
person.prototype;
▷ prototype chain
자식은 부모로부터 자기가 물려받은 유전자를 활용할 수 있다. 바로 prototype chain 때문이다.
prototype chain이란?
-
proto 프로퍼티가 가리키는 링크를 따라 부모 역할을 하는 프로토타입 객체의 프로퍼티나 메소드를 차례로 검색하는 것을 말한다.
-
proto 프로퍼티를 통해 상위 [[Prototype]]에 접근 가능하다.
어떤 방식으로 검색할까?
내가 있으면 내 변수나 메소드를 활용 없으면 부모 변수,메소드 .proto 로 접근 없으면 부부모 .proto.proto 로 접근 …(최초 부모까지 계속 접근 시도)하는 방식으로 검색한다.
📎참조
- https://velog.io/@h0ngwon/Javascript-proto-vs-prototype-%EC%B0%A8%EC%9D%B4
- https://velog.io/@goggling/Prototype%EA%B3%BC-proto-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B01
댓글남기기