※ 본 카테고리의 내용은 부스트캠프 챌린지 기간동안 학습한 내용을 바탕으로 정리한 내용입니다.
목차
0. 클래스, 객체, 인스턴스
클래스(Class)는 객체를 생성하기 위한 템플릿입니다.데이터와 이를 조작하는 코드를 하나로 추상화하는 목적을 가지고 만들어지는데, 자바스크립트에서는 원래 사용되지 않았다가 ES6부터 class라는 명령어를 사용해서 사용할 수 있게 되었습니다.
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
클래스에는 위에 예를 보시면 아실 수 있는 생성자(Constructor)라는 요소가 존재합니다.
constructor 메소드는 class로 생성된 객체를 생성하고 초기화하기 위한 특수한 메소드로, 클래스 안에 단 한 개만 존재할 수 있습니다.
예시를 조금 더 살펴보겠습니다.
Rectangle이라는 클래스는 내부 constructor의 매개변수로 height와 width를 받고 있는데, 이 매개변수는 Rectangle 클래스로 객체를 생성할 때 받게 됩니다.
받은 값들을 Rectangle이라는 클래스 내의 height와 width라는 변수 안에 넣은 것이고, 매개변수로 받은 값과 클래스 내부 값을 구분하기 위해서 this라는 구분자를 사용하게 됩니다.
위에서 말했다시피 자바스크립트는 사용만 할 수 있게 해 두었다 뿐이지 실제로는 클래스라는 개념을 사용하지 않습니다. 대신 객체는 존재하죠.
자바스크립트에서의 객체는 데이터와 함수의 집합입니다.
객체 안에는 데이터와 함수들이 들어있는데, 각각 프로퍼티(property)와 메소드(method)라고 부릅니다.
let person = {
name: ['Bob', 'Smith'],
age: 32,
gender: 'male',
interests: ['music', 'skiing'],
bio: function() {
alert(this.name[0] + ' ' + this.name[1] + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
},
greeting: function() {
alert('Hi! I\'m ' + this.name[0] + '.');
}
};
위 예시는 모질라에서 제공하는 객체의 기본 예제입니다.
이 객체의 프로퍼티 혹은 메소드에 접근을 하기 위해서는 .을 이용하면 됩니다.
person.name, person.age, person.interests[1], person.greeting()
과 같은 형식으로 사용할 수 있는 것이죠.
이제 인스턴스에 대해서 알아봅시다.
인스턴스는 클래스로부터 찍어낸 객체를 의미합니다.
하지만 이것은 자바스크립트에서는 엄밀하게 말하면 완벽한 정의는 아닙니다.
자바스크립트에는 다른 언어들과 같은 클래스가 존재하지 않기 때문이죠(!)
인스턴스에 대해서 더 명확하게 알기 위해서는 프로토타입에 대해서 공부해야 합니다.
아래는 위에서 만든 Rectangle 클래스를 이용한 a라는 인스턴스입니다.
let a = new Rectangle(5,3); // 높이가 5이고, 너비가 3인 a라는 이름의 사각형
1. 프로토타입
다시 한번 강조드리지만 자바스크립트라는 언어에는 클래스라는 개념이 없(었)습니다.
그래서 이전에는 function()이라는 이름으로 새로운 객체를 추가하곤 했죠.
그렇다면 클래스 대신 자바스크립트의 핵심이 되는 프로토타입에 대해서 예를 통해서 알아보도록 하겠습니다.
Person이라는 아무것도 없는 함수를 만든다고 생각해봅시다.
이때 Person을 우리가 만든 것 같지만, Person함수 내부에 있는 프로토타입 속성은 프로토타입 객체를 참조합니다.
Person함수를 통해 만든 객체들 역시 같은 프로토타입 객체를 참조하게 됩니다.
function Person(){}
let joon = new Person();
let jisoo = new Person();
함수를 정의했을 때 다른 곳에 생성되는 프로토타입 객체는 자신이 다른 객체의 원형이 되는 객체입니다.
모든 객체는 프로토타입 객체에 접근할 수 있고, 프로토타입 객체도 동적으로 멤버를 추가할 수 있고, 이 프로토타입을 원형으로 복사된 모든 객체들도 추가된 멤버를 사용할 수 있습니다.
프로토타입 객체의 요소에도 접근할 수 있다고 말했는데, 바로 Person.prototype.getType 형태를 이용하면 가능합니다.
프로토타입 객체에 멤버를 추가, 수정, 삭제할 때는 함수 안의 prototype 속성을 사용해야 하지만, 프로토타입 멤버들을 읽을 때에는 함수 안의 prototype 속성 또는 객체 이름으로 접근해야 합니다.
(만들 때는 Person.prototype.getType으로 만들지만, 각 객체에서 확인할 때에는 jisoo.getType()와 같은 방식으로 확인!!)
여기까지만 오셔도 이제 모질라 재단에서 mdn에서 함수(메소드)들을 설명할 때 항상 중간에 prototype이 들어갔는지 조금이나마 이해가 되셨을 것이라고 생각합니다!
function Person(){}
let joon = new Person();
let jisoo = new Person();
Person.prototype.getType = function(){
return "인간";
};
console.log(joon.getType()); // 인간
console.log(jisoo.getType()); // 인간
그렇다면 다시 본론으로 돌아와서 프로토타입이 뭘까요?
자바스크립트에서는 기본 데이터 타입을 제외한 모든 것이 객체입니다.
객체가 만들어지기 위해서는 자신을 만드는 데 사용된 원형인 프로토타입 객체를 이용해서 객체를 만듭니다.
이 때 객체 안에자신을 만들어낸 원형을 의미하는 프로토타입 객체를 참조하는 __proto__ (비표준) 속성이라는 숨겨진 링크가 있습니다.
프로토타입 객체가 자식들에게 물려준 DNA라고 보면 되겠죠?
이 숨겨진 링크를 바로 프로토타입이라고 정의할 수 있습니다.
함수의 멤버인 prototype 속성은 프로토타입 객체를 참조하는 속성이고, 함수와 new 연산자가 만나 생성한 객체의 프로토타입 객체를 지정해주는 역할을 합니다.
__proto__ (비표준) 속성은 자신을 만들어낸 원형인 프로토타입 객체를 참조하는 숨겨진 링크로써 프로토타입을 의미하는 것이죠.
조금 다르지만, 자신의 원형을 참조한다는 점에서 그 역할은 비슷하죠?!
아무튼 결과적으로 자바스크립트에서는 숨겨진 링크가 있어서 프로토타입 객체 멤버에 접근할 수 있습니다.
그래서 이 프로토타입 링크를 사용자가 정의한 객체(joon이나 jisoo같은!!)에 링크가 참조되도록 설정하면 코드의 재사용과 객체 지향적인 프로그래밍을 할 수 있게 되는 것이죠.
다른 언어의 클래스와 같은 역할을 자바스크립트에서는 프로토타입이 담당하고 있다고 생각하시면 됩니다!!
코드의 재사용에 대해서도 간략히 다루고 넘어가겠습니다.
다른 언어에서의 상속을 통한 코드의 재사용을 자바스크립트에서는 프로토타입을 통해 할 수 있습니다.
일반적인 classical 방식과 자바스크립트에서 주로 사용하는 prototypal 방식이 있는데, 자바스크립트에서는 후자를 더 선호합니다.
보다 간결하게 구현할 수 있기 때문이죠.
그래도 하나만 공부하기에는 좀 아쉬우니 두 가지 방법을 모두 살펴보죠!
1.0. Classical 방식
Person.prototype.getName = function(){
return this.name;
};
function Korean(name){
this.name = name;
}
Korean.prototype = Person.prototype;
var kor1 = new Korean("지수");
console.log(kor1.getName()); // 지수
위 예시는 자식 함수의 프로토타입 속성을 부모 함수의 프로토타입 속성이 참조하는 객체로 설정했습니다.
자식 함수를 통해 생성된 객체는 부모 함수를 통해 생성된 객체를 거치지 않고 부모 함수의 프로토타입 객체를 부모로 바로 지정해서 객체를 생성합니다.
일반적인 방식중에서도 많이 개선된 방식이지만, 총 세 단계가 필요합니다.
1.1. Prototypal 방식
var person = {
type : "인간",
getType : function(){
return this.type;
},
getName : function(){
return this.name;
}
};
var joon = Object.create(person);
joon.name = "혁준";
console.log(joon.getType()); // 인간
console.log(joon.getName()); // 혁준
이번에는 Object.create()를 사용하여 객체 생성과 프로토타입 객체 지정을 동시에 했습니다.
이 함수는 첫 번째 매개변수(person)은 부모 객체로 사용할 객체를 넘겨주고, 두 번째 매개변수로는 반환되는 자식 객체의 속성에 추가되는 부분이 됩니다. (두 번째 매개변수는 없어도 괜찮습니다.)
이렇게 객체 생성과 동시에 부모객체를 지정해서 코드의 재활용을 간단하게 구현할 수 있게 되었습니다.
위에서는 부모 객체, 자식 객체, prototype을 넘겨받는 과정이 있었는데, 세 과정이 두 과정(부모 객체 생성, 자식 객체 생성 + 프로토타입 할당)으로 줄었으니, 최소 50%의 효율이라고 볼 수 있겠죠?!!
자바스크립트의 프로토타입에 대해서 더 자세하게 알고 싶으신 분은 아래 두 블로그를 참조하시면 좋습니다!
(제 설명의 대부분의 내용은 첫 번째 블로그에서 참조했습니다. 좋은 자료 남겨주셔서 정말 감사합니다!)
JavaScript : 프로토타입(prototype) 이해
JavaScript는 클래스라는 개념이 없습니다. 그래서 기존의 객체를 복사하여(cloning) 새로운 객체를 생성하는 프로토타입 기반의 언어입니다. 프로토타입 기반 언어는 객체 원형인 프로토타입을 이
www.nextree.co.kr
Javascript 기초 - Object prototype 이해하기 | Insanehong's Incorrect Note
소개 이번 글에서 다룰 내용은 자바스크립트의 프로토타입 상속(prototypal inheritance) 이라는 확장과 객체의 재사용을 가능하게 해주며 class 기반으로 인스턴스를 생성하지 않는 자바스크립트에서
insanehong.kr
최근댓글