프로토타입

primav·2024년 9월 24일

Javascript

목록 보기
9/14
post-thumbnail

프로토타입을 공부하던 중 너무 이해가 안돼서 따로 동영상을 찾아봤는데 제일 이해가 잘 되는 영상이라 공유한다!
코딩애플 - 프로토타입

코딩애플 - 프로토타입 정리

비슷한 객체들을 쉽게 만들고 싶다면, 생성자 함수를 사용한다.

생성자 함수

✔️ 생성자 함수

function 기계() { // 부모
 	this.q = 'strike'; // 자식에게 q, w 물려줌
  	this.w = 'snowball';
  // 여기에 작성하면 
  // 자식이 {q : 'strike`} 직접 가짐
}

var nunu = new 기계() // 자식

부모가 자식을 생산하는 느낌으로 이해하면 된다. 하지만 이 방법 말고도 prototype을 사용하여 자식 object 에게 데이터를 물려줄 수 있다.

프로토타입

✔️ Prototype

function 기계() { // 부모
 	this.q = 'strike'; // 자식에게 q, w 물려줌
  	this.w = 'snowball';
}

기계.prototype.name = 'kim' // 기계.prototype도 객체이므로 객체에 Name 프로퍼티 추가

// 여기에 작성하면 
// 부모만 {name: 'kim'} 가짐
var nunu = new 기계() // 자식

요약하자면, 자식 객체에게 데이터를 물려주는 방법은 두가지가 있는 것이다.

  1. 생성자 함수
  2. Prototype

생성자 함수 vs 프로토타입

생성자 함수Prototype
생성자 함수 내부에서 this 키워드를 사용하여 자식 객체에 속성을 직접 할당부모 객체의 prototype에 속성을 추가하면 자식 객체가 해당 속성에 접근
메모리 효율 좋음
자식 객체가 해당 속성 복사하는 것이 아니라, 부모의 prototype 체인에서 상속받아 사용
직접적인 상속간접적인 상속
자식이 직접 가짐부모가 가짐
객체가 생성될 때마다 새로운 속성들이 그 객체에 복사되는 방식자식 객체가 부모 객체의 속성을 참조
자식 객체는 해당 속성들의 개별 복사본을 가짐 --> 각자 값 변경 가능같은 속성을 여러 객체가 공유

➡️ Prototype 은 상속 개념을 통해 여러 객체 간에 공통된 데이터를 공유하는 데 유용하다.

프로토타입

유전자라고 생각하자!
부모에게 물려받는 것이라고 생각하는 것이다.

부모 유전자에 있는 것을 자식이 사용 가능한 이유는 무엇일까?

function 기계() { // 부모
 	this.q = 'strike'; // 자식에게 q, w 물려줌
  	this.w = 'snowball';
}

기계.prototype.name = 'kim' 

var nunu = new 기계() // 자식

nunu.name

이 때 nunu라는 객체에서 nunu.name라는 자료를 뽑으려고 한다면 순서는 다음과 같다.

  1. nununame 을 가지고 있는지 확인
  2. 가지고 있지 않으면 nunu 부모 유전자를 확인 --> 거기에 name이 있으면 출력
  3. 없으면 부모의 부모 유전자까지 확인을 한다.

➡️ Prototype Chain

이미 우리는 prototype을 사용하고 있었다

array.length, array.sort()와 같은 함수들을 사용해본 적이 있는가?
자바스크립트를 사용해봤다면 이러한 배열의 내장 함수들은 당연히 사용해봤을 것이다.

그렇다면 이러한 함수들은 우리가 지정도 하지 않았는데 어떻게 사용할 수 있는 것일까?
여기서 prototype 이라는 개념이 사용된다.

array에 .sort()를 붙일 수 있는 이유

우리는 var array1 = [4, 2, 1] 라는 객체 리터럴 방식으로 배열을 할당한다.
하지만 이것은 var array1 = new Array(4, 2, 1) 이라는 생성자 함수와 같은 역할이다.

밑의 방식 처럼 진행한다면 Array라는 부모가 array1 이라는 자식을 생산해낸 것이다.
이 때 Array라는 부모에는 아래와 같이 다양한 유전자들이 존재한다.
array1Array의 자식이므로 유전자를 물려받아 함수들을 사용할 수 있는 것이다!!

수업 시간에 배운 내용 정리

여기서 부터는 유튜브에 나와있던 것이 아니라 수업시간에 배웠던 내용을 정리한 내용이다!

프로토타입

객체 간 따로따로 유지해야 하는 데이터, 공통으로 유지해야하는 데이터 중 공통으로 유지해야하는 데이터를 담기 위한 곳이다.

➡️ 원하는 프로퍼티, 메서드를 여러 객체가 공통으로 이용하게끔 할 수 있다.

함수를 선언하면 자동으로 그 함수를 위한 프로토타입 객체가 만들어진다.

❗️ 함수를 이용해 객체를 생성해야 만들어지는 것이 아니라 함수를 선언하는 것만으로도 자동으로 프로토타입 객체가 만들어진다. (일반 함수에서도 프로토타입 생성!)

하지만 일반 함수에서도 프로토타입은 만들어지지만 무시되고, new 연산자를 이용한 생성자 함수에서는 프로토타입이 사용된다.

생성자 함수로 사용될때 변수, 함수가 담긴 공간으로 이해하자!

프로토타입 객체에는 자동으로 constructor라는 생성자가 추가되어 있다.
함수를 이용해 객체를 생성한다는 의미는 사실 내부적으로 프로토타입의 생성자를 이용하는 것이다.

User라는 함수를 이용해 new User() 로 객체를 생성하게 되면,

  1. User 함수의 프로토 타입 객체 내의 constructor() 생성자 이용
  2. 이 생성자에 의해 객체 생성

멤버 추가

  • 프로토타입에 멤버 등록 - 함수명.prototype.멤버명
  • 프로토타입의 멤버를 함수의 객체에서 이용 - 객체명.멤버명
function User() {
 	User.prototype.name = '홍길동';
}
User.prototype.age = 20;

let user1 = new User();
let user2 = new User();

console.log(user1.name, user1.age); // 홍길동 20 

console.log(user1.__proto__.name, user1.__proto__.age) ;// 홍길동 20

프로토타입과 this

function User(name, age, address) {
 	this.name = name; // 함수 내에서 this 이용하여 지정 --> 자식에게만 지정
  	this.age = age; // 함수 내에서 this 이용하여 지정 --> 자식에게만 지정
  	User.prototype.address = address; // 프로토타입으로 지정 --> 아예 부모를 바꿔버림
}

let user1 = new User('홍길동', 20, 'Seoul') 
let user2 = new User('김길동', 30, 'Busan')

cosole.log(user1.name, user1.age, user1.address) // 홍길동 20 busan
console.log(user2.name, user2.age, user2.addrdess) // 김길동 30 busan

this프로토타입에 동일 이름의 멤버 선언이 가능하다.
이때는 this에 선언된 멤버가 이용된다.

자신의 메모리에서 먼저 찾고 없는 경우에만! 내부 참조를 이용해 프로토타입의 멤버에 접근하는 것이다.
(자신에게 없는 유전자를 부모, 부모의 부모 등으로 찾으러 거슬러 올라감)

function User(name) 
	this.name = name;
	User.prototype.name = name;
}

✔️ 특정 객체에만 선언하여 다른 값 넣기

function User(name) {
 	this.name = name;
  	User.prototype.point = 20;
  	User.prototype.sayHello = function() {
    console.log(`Hello ${this.name}, point: ${this.point}`)
}

let user1 = new User('Honggildong')
user1.sayHello() // Hello Honggildnog, point:20

let user2 = new User('Kimgildong')
user2.point = 30;
user2.sayHello = function () { } // Hello Kimgildnog, point:30
  
let user3 = new User('Leegildong')
user3.sayHello() // Hello Leegildnog, point:20

메모리 효율성

함수를 this에 선언하면 동일한 동작을 하는 메서드가 객체별로 매번 메모리에 할당되어 불필요하게 점유하는 상황이 발생한다.

✔️ this 이용 - 메모리 낭비

✔️ 프로토타입 이용

상속 구현

어떤 객체에 선언된 멤버를 그대로 이어 받아 새로운 객체를 선언하는 방법을오 프로토타입을 이용해 구현할 수 있다.

상위 객체를 하위 프로토타입으로 지정

상위 함수의 객체를 하위 함수의 프로토타입으로 지정한다.
이렇게 하면 상위에 선언된 것을 하위에서 이용하게 할 수 있다.

상위의 프로토타입을 하위 프로토타입으로 지정

  • 상위 객체가 생성되어야 한다.

0개의 댓글