먼저 다른 Back-end에는 클래스(Class)라는 개념이 존재한다.
Java, Python, Ruby 등 객체지향언어에서 빠질 수 없는 개념이다.
하지만 JavaScript에는 클래스라는 개념이 없다.
그런데 중요한 점은 자바스크립트도 객체지향언어라는 것입니다.
대신 프로토타입(Prototype)이라는 것이 존재한다.
JavaScript가 프로토타입 기반 언어라고 불리는 이유이다.
프로토타입이란?
자바스크립트의 모든 객체는 최소한 하나 이상의 다른 객체로부터 상속을 받으며, 이때 상속되는 정보를 제공하는 객체를 프로토타입(prototype)이라고 한다.
즉, 객체 지향의 상속 개념과 같이 부모 객체의 프로퍼티 또는 메서드를 상속받아 사용할 수 있게 한다.
이때 상속되는 정보를 제공하는 부모 객체를 Prototype(프로토타입) 객체
또는 줄여서 Prototype(프로토타입)
이라 한다.
ECMA6 표준에서는 Class 문법이 추가되었다. 하지만 문법이 추가되었다는 것이지, 자바스크립트가 클래스 기반으로 바뀌었다는 것은 아니다.
자바스크립트에 클래스는 없지만 함수(function)와 new를 통해 클래스를 비스무리하게 흉내낼 수 있다.
function Person(name, first, second, third){
this.name=name;
this.first=first;
this.second=second;
this.sum = function(){
return this.first+this.second;
}
}
var kim = new Person('kim', 10, 20); //30
var lee = new Person('lee', 10, 10); //20
console.log("kim.sum()", kim.sum());
console.log("lee.sum()", lee.sum());
위 예제에서
생성자로 만들어진 객체(Person)에 있는 메서드가 객체들(kim과 lee)마다 실행되어 객체들 각각에 할당이 되기 때문에 성능이 떨어지고 메모리의 사용도 많아지게 된다.
만약 객체를 여러 개 만들면 그만큼의 변수가 메모리에 할당되게 될 것이다.
이러한 문제를 프로토타입으로 해결할 수 있다.
function Person(name, first, second, third){
this.name=name;
this.first=first;
this.second=second;
}
Person.prototype.sum = function(){
return this.first+this.second;
}
var kim = new Person('kim', 10, 20); //30
var lee = new Person('lee', 10, 10); //20
console.log("kim.sum()", kim.sum());
console.log("lee.sum()", lee.sum());
위 코드는 이전 코드와 같은 결과값을 가진다.
하지만!!
sum 함수를 생성자 밖에서 prototype으로 메서드를 선언해 주면 많은 객체가 생성되더라도 메서드는 한 번만 생성되므로 성능 저하, 메모리 낭비가 개선된다.
function Person() {} // => 함수
var foo = new Person(); // => 함수로 객체를 생성
위 코드처럼 객체는 언제나 함수에서 생성된다.
일반적인 객체도 생성도 마찬가지다.
var obj = {}; //일반적인 객체 생성
위 객체를 풀어쓰면 var obj = new Object();
가 된다.
Object()
라는 함수를 내장하고 있다.
이렇듯 객체는 함수에서 시작된다.
자바스크립트는 Object와 마찬가지로 Function, Array도 모두 함수로 정의되어 있다.
함수를 정의하면 함수만 생성되는 것이 아니라 Prototype Object도 같이 생성이 된다.
생성된 함수의 prototype 프로퍼티를 통해 Prototype Objec에 접근이 가능하다.
- Prototype Object는 일반적인 객체와 같다.
- 기본적인 속성으로
constructor
와__proto__
를 가지고 있다.
constructor 프로퍼티는 자신을 생성한 함수를 가리킨다.
constructor 자격이 부여되면 new를 통해 객체를 만들어 낼 수 있게 됩니다. 이것이 함수만 new 키워드를 사용할 수 있는 이유입니다.
function Person() {}
var foo = new Person();
위 코드에서
Person() 생성자 함수에 의해 생성된 객체를 foo가 있다.
이때 foo 객체의 프로토타입 객체는 Person.prototype이다.
따라서 Person.prototype의 constructor 프로퍼티는 Person() 생성자 함수를 가리킨다.
__proto__
프로퍼티__proto__
는 Prototype Link입니다.
function Person() {}
Person.prototype.eyes = 2;
Person.prototype.nose = 1;
var kim = new Person();
var park = new Person():
console.log(kim.eyes); // => 2
Kim이 가지고 있는 __proto__
이 가리키는 링크를 따라 자신의 부모 역할을 하는 프로토타입 객체(Person.prototype)의 프로퍼티나 메서드를 차례대로 검색한다.
최상위인 Object의 Prototype Object까지 도달했는데도 못 찾았을 경우 undefined를 리턴합니다.
⭐️ 최상위인 Object.prototype 객체는 어떠한 프로토타입도 가지지 않으며, 아무런 프로퍼티도 상속받지 않습니다.
⭐️ Object.prototype 객체는 프로토타입 체인에서도 가장 상위에 존재하는 프로토타입이다.
⭐️ 자바스크립트의 모든 객체는 Object.prototype 객체를 프로토타입으로 상속받는다.
자바스크립트에는 class라는 개념이 없는대신 프로토타입이 있다. 프로토타입(Prototype)은 객체 지향의 class의 상속 개념과 같은것이다.
프로토타입은 함수와 객체를 통해 상속(부모객체의 프로퍼티,메소드)을 받는다.
함수가 정의 될때 함수와 해당함수의 프로토타입 객체가 생성된다.
3-1. 함수
3-2.프로토타입 객체
constructor
와 __proto__
를 가지고 있다.생성자 함수로부터 생성된 객체의 프로토타입 객체는
생성자 함수의 프로토타입 객체를 가리킨다.
파도파도 끝이 없이 모르는게 나온다..
JavaScript 프로토타입 이해하기 (오승환님)
이 블로그를 통해서 조금은 이해한거 같다ㅠㅠ