[elice] 프로퍼티 어트리뷰트와 생성자 함수

yuna·2023년 5월 30일
0

elice

목록 보기
2/14
post-thumbnail

🔸 내부슬롯, 내부 메서드

내부 슬롯과 내부 메서드 란, 자바스크립트 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript 사양
에서 사용하는 의사 프로퍼티(pseudo property)의사 메서드(psuedo method) 다. ECMAScript 사양에 등장하는 이중 대괄호([[…]])로 감싼 이름들이 내부 슬롯과 내부 메서드다.

🔸 프로퍼티 어트리뷰트

프로퍼티 상태에는 프로퍼티 값(value), 값의 갱신 가능 여부(writable), 열거 가능 여부(enumerable), 재정의 가능 여부(configurable) 가 있다.

🔸 데이터 프로퍼티 vs 접근자 프로퍼티

데이터 프로퍼티 : 키와 값으로 구성된 일반적인 프로퍼티이며 데이터 프로퍼티의 어트리뷰트는 기본값(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가 가리킬 객체)이다.

생성자 함수 인스턴스 생성 과정

  1. 인스턴스 생성과 this 바인딩
    • 처음 생성자 함수를 초기화하면, 빈 객체가 생성되는데 이 빈 객체가 바로 인스턴스가 된다.
    • 인스턴스는 this에 바인딩되며, 해당 과정은 런타임 이전에 실행된다.

  2. 인스턴스 초기화
    • 생성자 함수에 기술되어 있는 코드가 한 줄씩 실행되어 this에 바인딩되어 있는 인스턴스를 초기화한다.
    • 프로퍼티, 메서드가 추가되고 인수로 전달받은 초기값을 프로퍼티에 할당한다.

  3. 인스턴스 반환
    • 바인딩된 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]]과 [[Construct]]

함수가 일반 함수로서 호출되면 [[Call]]이 호출되고 new 연산자와 함께 생성자 함수로서 호출되면 [[Construct]]가 호출된다.

내부 메서드 [[Call]]을 갖는 함수 객체를 callable 이라고 하며, 내부 메서드 [[Construct]]를 갖는 함수 객체를 constructor, 갖지 않는 객체를 non-constructor 라 부른다. 함수 객체는 반드시 callable이어야 하지만 모든 함수 객체가 [[Construct]]를 갖는 것은 아니다

  • Constructor
    • 함수 선언문
    • 함수 표현식
    • 클래스

  • Non-Constructor
    • 메서드(ES6 메서드 축약표현)
    • 화살표 함수

0개의 댓글