class Exam {
#kor = 0; // private(은닉) 변수 <- 외부에서 접근 불가
math = 0; // public(공개) 변수 <- 외부에서 접근 가능
// 생성자
constructor(kor = 0, math = 0) {
this.#kor = kor;
this.math = math;
}
// 인스턴스 메서드 <- 해당 클래스를 통해 생성된 인스턴스가 사용 가능
total() {
return this.#kor + this.math;
}
// 정적 메서드 <- Exam.create()와 같이 사용
static create() {
return new Exam();
}
// getter <- private 변수에 접근할 수 있는 도구
get kor() {
return this.#kor;
}
// setter <- private 변수를 변경할 수 있는 도구
set kor(value) {
this.#kor = value;
}
}
let exam = new Exam(10, 20);
console.log(exam.total()); // 30
console.log(Exam.create()); // Exam {math: 0, #kor:0}
console.log(exam.kor); // 10
exam.kor = 10;
// getter, setter는 괄호를 쓰지 않음
프로토타입 체인이란 어떤 데이터의 __proto__(data.constructor.prototype)프로퍼티 내부에 다시 __proto__프로퍼티가 연쇄적으로 이어진 것을 말하고, 그 체인을 따라가면서 검색하는 것을 프로토타입 체이닝(prototype chaining)이라고 한다.
아래의 스크린샷을 보면, Boolean 생성자를 통해 만들어진 b라는 변수의 [[Prototype]](__proto__) 프로퍼티가 Boolean을 가리키고, 그 안에 있는 toString, valueOf와 같은 인스턴스 메서드를 사용할 수 있다.
그런데, 그 안에 또 [[Prototype]](__proto__) 프로퍼티가 있고, 이 프로퍼티는 Object를 가리키고 있기 때문에, 사실 b 변수는 Object의 인스턴스 메서드도 사용할 수 있다.
많은 JavaScript 개발자들은 Java같은 다른 객체지향 언어처럼 상속 기능을 사용하고 싶어 했다. 하지만, ES6 버전 이전의 JavaScript에는class 문법이 없었기 때문에, 프로토타입 체이닝을 활용해 클래스의 상속과 비슷하게 구현하여 사용하고자 했다.
아래의 코드를 보자.
var Test = function() {
for(var i = 0; i < arguments.length; i++) {
this[i] = arguments[i];
}
this.length = arguments.length;
}
Test.prototype = [];
var t = new Test(1,2,3,4,5);
여기서 Test 생성자는 Array의 instance인 []를 prototype으로 가진다.
Test 생성자를 호출해 만들어진 instance는 Test의 prototype의 속성(인스턴스 메서드)을 사용할 수 있고, Test의 prototype은 Array의 instance이므로 Array의 prototype의 속성을 사용할 수 있다.
따라서, Test의 instance는 Array의 prototype의 속성을 사용할 수 있는 것이다.
JavaScript ES6버전에서 class 문법이 추가되면서 상속을 지원하게 되었다.
하지만, JavaScript는 프로토타입 기반 언어이기 때문에 class 문법도 내부적으로는 프로토타입 체이닝을 활용하도록 구성되어 있다.
class를 통한 상속은 아래와 같이 사용할 수 있다.
class Test extends String {
constructor() {
super(); // 생략 가능
}
}
let t = new Test();
위의 코드를 실행하고 객체 t의 프로퍼티를 살펴보면 아래 스크린샷과 같다.
Test 객체 t의 constructor는 class Test이고 프로토타입 체이닝을 통해 따라 올라가면, 그 [[Prototype]]의 constructor는 String 생성자인 것을 확인할 수 있다.
아래의 이미지를 보면 t의 [[Prototype]]의 [[Prototype]]이 String 생성자를 통해 만든 instance의 [[Prototype]]과 같은 것을 보니 상속이 잘 이루어지고 있다.
