객체(Object)

@bbearcookie · May 27, 2023 · 8 min read

자바스크립트 언어의 타입은 원시 값객체로 나뉜다.
원시 값이 아닌 타입은 모두 Object 타입을 프로토타입 체인의 최상단에 놓기 때문에 ArrayFunction 같은 타입도 모두 객체에 해당된다.

자바스크립트에서는 Object 타입을 통해 복잡한 엔티티를 표현하고, 프로토타입이라는 개념을 통해서 객체지향 패러다임을 구현한다.

원시 값
boolean null undefined number bigint string symbol 등이 있다.

객체 표현

자바스크립트에서 객체는 key-value 형태로 여러 프로퍼티나 메소드를 표현한다.
따라서 객체를 가장 기본적인 형태인 객체 리터럴로 표현하자면 아래와 같이 생겼다:

let kim = {
  name: '김철수',
  age: 20,
  showAge: function() { // 함수 프로퍼티
    console.log(`저는 ${this.age}세 입니다.`);
  },
  showName() { // 메소드
    console.log(`제 이름은 ${this.name}입니다.`);
  }
}

console.log(kim.name); // 김철수
kim.showAge(); // 저는 20세 입니다.
kim.showName(); // 제 이름은 김철수입니다.

kim 객체가 가지고 있는 프로퍼티는 name, age, showAge() 이고
가지고 있는 메소드는 showName() 이다.

여기서 주의할 점은 showAge() 는 ES6에 등장한 메소드 정의 구문을 이용하지 않았기 때문에 메소드가 아니라 단순히 함수를 값으로 가진 프로퍼티라는 점이다.

프로퍼티

get

객체 내부의 프로퍼티는 점 표기법이나 괄호 표기법으로 가져올 수 있다.

kim.name // 점 표기법
kim["name"] // 괄호 표기법

delete

객체 내부의 프로퍼티는 delete 연산자로 제거할 수 있다.

delete kim.name;

in

객체 내부에 프로퍼티가 존재하는지의 여부는 in 연산자로 확인할 수 있다.

console.log("name" in kim);

프로퍼티 속성

객체 내부의 각각의 프로퍼티에는 프로퍼티의 값, 값의 갱신 가능 여부, 열거 가능 여부, 재정의 가능 여부 등의 다양한 속성 정보가 들어있다.

데이터 프로퍼티

  • value: 프로퍼티 키를 통해 프로퍼티 값에 접근하면 반환되는 값
  • writable: 프로퍼티 값의 변경 가능 여부
  • enumerable: 프로퍼티의 열거 가능 여부
  • configurable: 프로퍼티의 재정의 가능 여부

데이터 프로퍼티에 대해서는 Object.getOwnPropertyDescriptor() 함수를 통해서 조회할 수 있다.

let person = {
  name: 'Lee',
  age: 20
};

console.log(Object.getOwnPropertyDescriptor(person, 'name'));
console.log(Object.getOwnPropertyDescriptor(person, 'age'));

// { value: 'Lee', writable: true, enumerable: true, configurable: true }
// { value: 20, writable: true, enumerable: true, configurable: true }

접근자 프로퍼티

  • get: 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 읽을 때 호출되는 함수
  • set: 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 저장할 때 호출되는 함수
  • enumerable: 프로퍼티의 열거 가능 여부
  • configurable: 프로퍼티의 재정의 가능 여부

접근자 프로퍼티는 get 이나 set 키워드를 붙혀서 객체의 내부에 프로퍼티를 정의하여 사용한다.

let person = {
  firstName: 'Shin',
  lastName: 'Jjang-go',

  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  },

  set fullName(name) {
    [this.firstName, this.lastName] = name.split(' ');
  },
};

console.log(person.fullName); // Shin Jjang-go
person.fullName = '신 짱구';
console.log(person.fullName); // 신 짱구

프로퍼티 추가 및 수정

간단하게 프로퍼티 키에 대해서 값을 추가하거나 변경하는 방법도 있지만
Object.defineProperty() 함수를 사용하면 객체에 새로운 프로퍼티를 추가하거나 기존의 프로퍼티를 수정하면서 속성 정보도 함께 조작할 수 있다.

let person = {
  name: 'Lee',
  age: 20
};

Object.defineProperty(person, 'name', { value: 'Kim', enumerable: false });
Object.defineProperty(person, 'job', { value: 'developer', writable: true });

console.log(Object.getOwnPropertyDescriptor(person, 'name'));
console.log(Object.getOwnPropertyDescriptor(person, 'age'));
console.log(Object.getOwnPropertyDescriptor(person, 'job'));

// { value: 'Kim', writable: true, enumerable: false, configurable: true }
// { value: 20, writable: true, enumerable: true, configurable: true }
// { value: 'developer', writable: true, enumerable: false, configurable: false }

객체 생성

자바스크립트에서 객체를 생성하기 위해서는 객체 리터럴 방식, Object 빌트인 함수, 생성자 함수나 클래스를 new 연산자로 실행하는 방법이 있다.

객체 리터럴

중괄호 {} 를 사용해 그 안에 객체의 프로퍼티를 넣어주는 방식이다.

let kim = { 
  name: "김철수",
  showName() {
    console.log(`제 이름은 ${this.name}입니다.`);
  }
};

Object.create()

Object.create(proto, propertiesObject) 함수를 이용해서 객체를 생성하는 방법이다.

proto: 생성될 객체 내부의 __proto__ 가 가리키게 할 객체를 전달한다.
propertiesObject: 생성될 객체 내부의 프로퍼티와 속성을 입력한다. (선택사항)

function Person(name, age) {
  this.name = name;
  this.age = age;
}

const kim = Object.create(Person.prototype, {
  name: { writable: true, configurable: true, value: '김철수' },
  age: { writable: true, configurable: true, value: 20 },
});

console.log(kim.name); // 김철수
console.log(kim.age); // 20

new 연산자

new 연산자로 생성자 함수를 실행하는 방법이다.

생성자 함수

자바스크립트에서는 함수를 new 연산자로 실행할 경우 그 함수를 생성자 함수라고 하여 내부적으로 this 객체를 생성하고 반환하는 작업을 암묵적으로 수행한다.

만약 생성자 함수에서 반환하는 값이 있다면 그 값을 this 에 바인딩해서 사용한다.

function Person(name, age) {
  // this = {}; // 암시적으로 this 객체가 생성됨.

  this.name = name;
  this.age = age;
  this.showName = function() {
    console.log(`제 이름은 ${this.name} 입니다.`);
  };

  // return this; // 암시적으로 this 객체가 반환됨.
}

let kim = new Person("김철수", 20);
let lee = new Person("이미리", 25);

kim.showName(); // 제 이름은 김철수 입니다.
lee.showName(); // 제 이름은 이미리 입니다.

Object 생성자

직접 정의한 생성자 함수가 아니라 기본적으로 존재하는 Object 객체를 생성하는 방법도 있다.

let kim = new Object();

kim.name = "김철수";
kim.showName: function() { console.log(`제 이름은 ${this.name} 입니다.`); };

참고 자료

모던 자바스크립트 Deep Dive 16장 프로퍼티 어트리뷰트
JavaScript 객체 기본
JavaScript의 타입과 자료구조 (MDN)
Object.create() (MDN)
Object.defineProperty() (MDN)
객체 (코어 자바스크립트)
프로퍼티 getter와 setter (코어 자바스크립트)

@bbearcookie
Frontend Developer