TIL59. 프로토타입(1)개념

조연정·2020년 12월 28일
0

코어자바스크립트 chapter6의 내용 '프로토 타입'의 개념에 대해 알아보자.

prototype

프로토타입 = 자바스크립트
자바스크립트는 프로토타입기반 언어라고 불릴만큼 '프로토타입'은 js에서 핵심개념이다. 클래스기반언어에서는 '상속'을 사용하지만, 프로토타입기반언어에서는 어떤 객체를 원형(prototype)으로 삼고 이를 복제함으로써 상속과 비슷한 효과를 얻는다.

var instance = new Constructor();

위의 코드를 이해하고, 그림을 보며 문장을 만들 수 있다면 프로토타입의 이해는 끝난 것이다. ^^
=> new키워드(연산자)로 constructor를 호출하면, instance가 만들어지는데, 이 instance의 생략 가능한 프로퍼티인__proto__는 Constructor의 prototype을 참조한다.

위 문장을 이해하기 위해서 위에서 언급한 각각의 단어들에 대해서 알아보도록 해보자.

Instance

인스턴스라는 용어는 "객체(object)"와 유사하다.
의미상으로 "객체"는 좀더 일반적인 의미인 반면에 "인스턴스"라고 표현하면 "현재 생성된 바로 그 객체"라는 인스턴트한 뉘앙스로 좀 더 짙게 표현할 수 있다.
또는 어떤 클래스의 속성을 지니는 실존하는 개체를 일컬어 말한다.

Constructor(생성자)

1. 생성자 없이 만든 객체(노가다)

let cho = {
    name:'hye-mi',
    first:10,
    second:20,
    sum:function(){
        return this.first+this.second;
    }
}
let choi = {
    name:'ha-neol',
    first:10,
    second:15,
    sum:function(){
        return this.first+this.second;
    }
}

let  kim = {
    name:'bo-hyen',
    first:30,
    second:10,
    sum:function(){
        return this.first+this.second;
    }
}
console.log("cho.sum()", cho.sum());
console.log("choi.sum()", choi.sum());
console.log("kim.sum()", kim.sum());

=> 객체가 동작하는 방법을 바꾼다면(ex.객체에 third라는 속성을 추가해야 하는 경우) 해당하는 속성들을 일일히 다 바꿔줘야 하는 문제점이 발생한다.

2. 생성자로 만든 객체

function Person(name, first, second, third){
    this.name = name;
    this.first = first;
    this.second = second; 
    this.third = third;
    this.sum = function(){
        return this.first + this.second + this.third;
    }
}
let cho = new Person('hye-mi',10, 20, 30);
 console.log(cho);

// Person {
  name: 'hye-mi',
  first: 10,
  second: 20,
  third: 30,
  sum: [Function]
}

new연산자를 붙여주어 새로운 인스턴스가 만들어졌다는 것을 알려준다. new를 붙이면, Person함수는 더이상 기존의 일반적인 함수가 아니라, 객체를 생성하는 생성자함수가 된다. (new가 있다면 = 생생자 함수)

prototype의 필요한 이유

위의 코드에서 cho라는 객체를 생성할 때, Person이라는 함수를 생성자로서 동작시켰다. new 키워드로 인스턴스 만들 때 마다 sum함수를 정의해주어 메모리 낭비를 하게된다.
함수를 분리해서 prototype을 사용하게되면, Person이라는 생성자함수가 실행될때마다 나오는 것이 아니라 한번만 실행하게 된다.

function Person(name, first, second, third){
    this.name=name;
    this.first=first;
    this.second=second; 
    this.third=third;
}
 
Person.prototype.sum = function(){
    return 'prototype : '+ (this.first+this.second+this.third);
}
 
let cho = new Person('hye-mi', 10, 20, 30);
let choi = new Person('choi', 10, 10, 50);
console.log("cho.sum()", cho.sum());
console.log("choi.sum()", choi.sum());

Prototype과 Proto

proto

프로토를 통해 인스턴스와 객체 간의 상속관계를 자유롭게 설정할 수 있다.

let superObj = {superVal:'super'}
let subObj = {subVal:'sub'}
subObj.__proto__ = superObj;
console.log('subObj.subVal:', subObj.subVal);

//subObj의 'superVal'값을 바꾸는 경우
subObj.superVal = 'sub';
console.log('superObj.superVal:',);

⇒ superObj의 객체의 값을 바꿨을 뿐, __proto__가 가르키는 객체를 바꾼 것이 아니다. 즉, proto를 바꾸는 것이 아니다.

Prototype과 proto

  • 생성자 함수로 만든 객체(인스턴스)에서 __proto__는 생성자 함수의 prototype을 참조한다.
  • proto 프로퍼티는 생략이 가능하여, 생성자함수의 prototype에 어떤 메서드나 프로퍼티가 있다면 인스턴스에도 마치 자기 것처럼 해당 메서드나 프로퍼티에 접근할 수 있다.
profile
Lv.1🌷

0개의 댓글