내부 슬롯과 내부 메서드
란, 자바스크립트 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript 사양
에서 사용하는 의사 프로퍼티(pseudo property)
와 의사 메서드(psuedo method)
다. ECMAScript 사양에 등장하는 이중 대괄호([[…]])
로 감싼 이름들이 내부 슬롯과 내부 메서드다.
프로퍼티 상태에는 프로퍼티 값(value), 값의 갱신 가능 여부(writable), 열거 가능 여부(enumerable), 재정의 가능 여부(configurable)
가 있다.
데이터 프로퍼티
: 키와 값으로 구성된 일반적인 프로퍼티이며 데이터 프로퍼티의 어트리뷰트는 기본값(true)으로 정의한다.
접근자 프로퍼티
자체적으로 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장 시 사용하는 접근자 함수로 구성 된다.
프로퍼티를 읽고 쓰는 방식으로 getter, setter 함수
를 사용하며, JavaScript에서는 접근자 프로퍼티 방식
으로 이를 구현할 수 있다. 접근자 프로퍼티는 자체적으로 값을 가지지 않으며, 데이터 프로퍼티의 값을 읽거나 저장할 때 관여만 한다.
const person = {
firstName: "Daewon",
lastName: "Seo",
// getter 함수
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
// setter 함수
set fullName(name) {
[this.firstName, this.lastName] = name.split(" ");
},
};
// 데이터 프로퍼티를 통한 프로퍼티 값의 참조.
console.log(person.firstName + " " + person.lastName);
// 접근자 프로퍼티를 통한 프로퍼티 값의 저장.
// 접근자 프로퍼티 fullName에 값을 저장하면 setter 함수가 호출된다.
person.fullName = "Daeho Kim";
console.log(person);
// 접근자 프로퍼티를 통한 값의 참조
// 접근자 프로퍼티 fullName에 접근하면 getter 함수가 호출된다.
console.log(person.fullName);
// firstName은 데이터 프로퍼티다.
// 데이터 프로퍼티는 [[Value]], [[Writable]], [[Enumerable]], [[Configurable]]
// 프로퍼티 어트리뷰트를 갖는다.
let descriptor = Object.getOwnPropertyDescriptor(person, "firstName");
console.log(descriptor);
// fullName은 접근자 프로퍼티다.
// 접근자 프로퍼티는 [[Get]], [[Set]], [[Enumerable]], [[Configurable]]
// 프로퍼티 어트리뷰트를 갖는다.
descriptor = Object.getOwnPropertyDescriptor(person, "fullName");
console.log(descriptor);
생성자 함수(constructor)
란, new 연산자와 함께 호출하여 객체(인스턴스)를 생성하는 함수이다. 인스턴스(instance)
란, 생성자 함수에 의해 생성된 객체를 말한다.
Object 생성자 함수는 new 연산자와 함께 호출하여 빈 객체를 생성할 수 있으며, 프로퍼티 또는 메서드를 추가할 수 있다.
기존의 객체 리터럴로 생성한 방식은 단 하나의 객체만을 생성하기에 동일한 프로퍼티를 가진 객체를 여러 가지 생성해야 할 경우 비효율적이다.(일반적으로 프로퍼티 값이 다르더라도 메서드가 동일한 경우가 많음)
자바스크립트에서는 일반 함수와 동일하게 정의하고 new 연산자와 함꼐 호출하면 생성자 함수로 동작한다.
this는 객체 자신의 프로퍼티나 메서드를 참조하기 위한 자기 참조 변수(self-referencing variable)
다. this가 가리키는 값, 즉 this 바인딩은 함수 호출 방식에 따라 동적으로 결정된다. 바인딩이란, 식별자와 값을 연결하는 과정 (this-this가 가리킬 객체)이다.
생성자 함수 인스턴스 생성 과정
인스턴스 생성과 this 바인딩
• 처음 생성자 함수를 초기화하면, 빈 객체가 생성되는데 이 빈 객체가 바로 인스턴스가 된다.
• 인스턴스는 this에 바인딩되며, 해당 과정은 런타임 이전에 실행된다.
인스턴스 초기화
• 생성자 함수에 기술되어 있는 코드가 한 줄씩 실행되어 this에 바인딩되어 있는 인스턴스를 초기화한다.
• 프로퍼티, 메서드가 추가되고 인수로 전달받은 초기값을 프로퍼티에 할당한다.
인스턴스 반환
• 바인딩된 this가 암묵적으로 반환된다.
• 만약, this가 아닌 다른 객체를 명시적으로 반환하면 return 문에 명시한 객체가 반환되기 때문에 return 문을 생략해야 한다.
function Car(price) {
// 인스턴스 초기화
this.price = price;
this.curPrice = function () {
return 2 * this.price;
};
}
// 인스턴스 생성
const car = new Car(500);
console.log(car.price); // 500
console.log(car.curPrice()); // 1000
함수가 일반 함수로서 호출되면 [[Call]]이 호출되고 new 연산자와 함께 생성자 함수로서 호출되면 [[Construct]]가 호출된다.
내부 메서드 [[Call]]을 갖는 함수 객체를 callable
이라고 하며, 내부 메서드 [[Construct]]를 갖는 함수 객체를 constructor
, 갖지 않는 객체를 non-constructor
라 부른다. 함수 객체는 반드시 callable이어야 하지만 모든 함수 객체가 [[Construct]]를 갖는 것은 아니다
Constructor
• 함수 선언문
• 함수 표현식
• 클래스
Non-Constructor
• 메서드(ES6 메서드 축약표현)
• 화살표 함수