JavaScript Obejct

개요

https://codelearn.io/sharing/object-trong-javascript

JavaScript에서는 객체를 생성하는 방식이 여러가지가 존재하고 이러한 객체에 많은 기능들을 내포 하고 있습니다. 이번 블로그 포스팅을 통해 어떤 내용이 있는지 알아보도록 하겠습니다. 

 

객체 생성

JavaScript에서 객체를 생성하는 방법은 여러 가지가 있습니다. 여기 세 가지 일반적인 방법과 각각에 대한 예시를 소개합니다.

 

객체 리터럴을 사용한 객체 생성

가장 간단하고 직관적인 방법은 객체 리터럴을 사용하는 것입니다. 이는 중괄호 `{}` 안에 키-값 쌍을 나열하여 객체를 직접 선언합니다.

const car = {
  brand: "Ford",
  model: "Mustang",
  year: 1969,
  displayInfo: function() {
    return `${this.brand} ${this.model} (${this.year})`;
  }
};

console.log(car.displayInfo()); // Ford Mustang (1969)

 

클래스를 인스턴스화해서 객체 생성

`ES6`부터 `JavaScript`는 `class` 키워드를 도입하여 객체지향 프로그래밍의 클래스 기반 문법을 지원합니다. `class`를 정의하고 `new` 키워드를 사용하여 클래스의 인스턴스를 생성합니다.

class Car {
  constructor(brand, model, year) {
    this.brand = brand;
    this.model = model;
    this.year = year;
  }

  displayInfo() {
    return `${this.brand} ${this.model} (${this.year})`;
  }
}

const myCar = new Car("Ford", "Mustang", 1969);
console.log(myCar.displayInfo()); // Ford Mustang (1969)

 

생성자 함수를 사용한 객체 생성

함수를 사용하여 객체를 생성할 수도 있습니다. 이러한 함수를 생성자 함수라고 하며, 보통 대문자로 시작하는 이름을 사용합니다. 함수 내부에 `this`명령어가 존재하면 `new` 키워드와 함께 호출하고 함수가 객체를 반환합니다.

function Car(brand, model, year) {
  this.brand = brand;
  this.model = model;
  this.year = year;
  this.displayInfo = function() {
    return `${this.brand} ${this.model} (${this.year})`;
  };
}

const anotherCar = new Car("Chevrolet", "Camaro", 1970);
console.log(anotherCar.displayInfo()); // Chevrolet Camaro (1970)

하지만 `ArrowFunction`을 통한 생성자 함수는 인스턴스를 생성하는 것을 지원하지 않고 있으니 유의하시기 바랍니다.

const IdolModelArrow = (name, year)=>{
    this.name = name;
    this.year = year;
};

const yuJin3 = new IdolModelArrow('안유진', 2003); // TypeError: IdolModelArrow is not a constructor

 

위의 모든 방법들은 `JavaScript`에서 객체를 생성하고 사용할 수 있는 유효한 방법입니다. 선택은 주로 상황, 필요한 기능, 개인 또는 팀의 선호도에 따라 달라질 수 있습니다. 객체 리터럴은 간단한 객체를 빠르게 만들 때 유용하고, 클래스는 객체지향 프로그래밍을 선호할 때 적합하며, 생성자 함수는 클래스가 도입되기 전부터 사용되어 온 전통적인 방식입니다.

 

Property Attributes

`JavaScript`에서 우리는 객체의 속성을 관리하기 위해 속성의 특성을 정의할 수 있는 `Property Attributes`에 대해 알아야 합니다. 이러한 속성들은 객체의 행동을 세밀하게 제어할 수 있는 강력한 메커니즘을 제공합니다. 각 속성은 두 가지 형태로 나타날 수 있으며, 이는 데이터 프로퍼티(Data Properties)와 액세서 프로퍼티(Accessor Properties)입니다.

 

데이터 프로퍼티(Data Properties)

데이터 프로퍼티는 이름 그대로 값(value)을 가지는 속성입니다. 이들의 특징은 네 가지 키(attribute)로 나타납니다:

  • `value`: 실제 데이터 값을 담고 있습니다.
  • `writable`: 이 플래그가 `true`면 프로퍼티의 값이 변경 가능하며, `false`면 변경할 수 없는 읽기 전용 속성이 됩니다.
  • `enumerable`: 이 플래그가 `true`면 해당 프로퍼티는 `for...in` 루프나 `Object.keys()` 메서드 등을 통해 열거할 수 있습니다.
  • `configurable`: 이 플래그가 `true`면 프로퍼티의 삭제나 특성 변경이 가능하지만, `false`인 경우에는 불가능합니다.
Object.defineProperty(person, 'nationality', {
  value: 'American',
  writable: true,
  enumerable: true,
  configurable: false // 이 속성을 더 이상 변경하거나 삭제할 수 없습니다.
});

위의 예에서는 `Object.defineProperty()` 메서드를 사용하여 각 속성의 특성을 명시적으로 설정했습니다. 이렇게 설정된 속성 특성은 객체와 상호작용할 때 중요한 역할을 하며, 객체의 데이터와 메서드에 대한 접근 및 수정 방법을 세밀하게 제어할 수 있습니다.

 

액세서 프로퍼티(Accessor Properties)

액세서 프로퍼티는 값을 직접적으로 저장하지 않고, `get`과 `set`이라는 함수를 통해 간접적으로 다른 값을 읽거나 쓸 수 있는 메서드입니다.

  • get: 프로퍼티에 접근할 때 호출되는 함수로서, 실질적인 값을 반환합니다.
  • set: 프로퍼티에 값을 설정할 때 호출되는 함수로서, 값을 받아와서 필요한 처리를 한 후 저장합니다.
  • get과 set 메서드는 우리가 프로퍼티를 직접 조작하는 것처럼 보이게 하지만, 실제로는 함수를 통해 프로퍼티의 접근과 할당을 관리할 수 있게 해줍니다.

이러한 속성들은 `Object.defineProperty()` 메서드를 사용하여 명시적으로 설정할 수 있습니다. 이를 통해 개발자는 객체의 속성이 어떻게 동작하고, 어떻게 접근되며, 변경될 수 있는지에 대한 제어를 할 수 있습니다. 이는 객체의 캡슐화와 정보 은닉에 매우 유용한 방법입니다.

Object.defineProperty(person, 'fullName', {
  get() {
    return `${this.firstName} ${this.lastName}`;
  },
  set(name) {
    [this.firstName, this.lastName] = name.split(' ');
  },
  enumerable: true,
  configurable: true
});

person.fullName = 'Jane Doe';
console.log(person.fullName); // Jane Doe

 

불변 객체(Immutable Object)

`JavaScript`에서 객체는 기본적으로 가변(mutable)입니다. 즉, 객체의 속성을 자유롭게 추가, 수정 또는 삭제할 수 있습니다. 그러나 때때로 객체의 상태를 불변(immutable)으로 만들어서 예기치 않은 변화로부터 보호하고, 예측 가능한 코드 작성을 돕고 싶을 때가 있습니다. 불변 객체는 생성된 후에 그 상태가 변경될 수 없는 객체를 말합니다.

 

객체의 확장 가능성(Extensible)

객체의 확장 가능성은 객체에 새로운 속성을 추가할 수 있는지 여부를 나타냅니다. `Object.preventExtensions()` 메서드를 사용하면, 객체에 새로운 속성을 추가하는 것을 방지할 수 있습니다.

const book = { title: '1984' };
Object.preventExtensions(book);

book.author = 'George Orwell'; // 무시됩니다. book 객체는 확장 불가능
console.log(book.author); // undefined

 

객체 밀봉(Seal)

밀봉된 객체는 기존 속성의 변경은 허용하지만, 새로운 속성 추가나 기존 속성의 삭제는 허용하지 않습니다. `Object.seal()` 메서드를 사용하여 객체를 밀봉할 수 있습니다.

Object.seal(book);

book.title = 'Animal Farm'; // 변경 가능
delete book.title; // 삭제 불가능
console.log(book.title); // 'Animal Farm'

 

객체 동결(Freeze)

동결된 객체는 속성의 추가, 삭제, 변경이 모두 불가능합니다. `Object.freeze()` 메서드를 사용하면, 객체를 완전히 불변 상태로 만들 수 있습니다.

Object.freeze(book);

book.title = 'The Road to Wigan Pier'; // 변경 무시됨
delete book.title; // 삭제 무시됨
book.review = 'Excellent'; // 추가 무시됨
console.log(book.title); // 'Animal Farm'

동결된 객체는 가장 엄격한 불변성을 보장합니다. 어떠한 속성의 변경도 허용하지 않으므로, 객체의 상태가 완전히 예측 가능해집니다. 이는 특히 복잡한 어플리케이션에서 상태 관리를 간단하게 만들어 줄 수 있습니다.

불변성은 함수형 프로그래밍 패러다임에서 매우 중요한 개념으로, 사이드 이펙트(side effects)와 상태 변화(state mutations)를 방지하여 보다 안전하고 관리하기 쉬운 코드를 작성하는 데 도움을 줍니다.

`Object.preventExtensions()`, `Object.seal()`, 그리고 `Object.freeze()` 메서드는 개발자가 객체의 변경 가능성을 엄격하게 제어할 수 있는 강력한 도구들입니다. 이러한 메서드를 적절히 활용하면, 코드의 복잡성을 줄이고, 런타임 에러의 가능성을 낮출 수 있습니다.

 

 

 

'Language > JavaScript' 카테고리의 다른 글

JavaScript Prototype  (0) 2023.11.05
JavaScript Class  (0) 2023.11.05
JavaScript Symbol - 심볼  (0) 2023.10.24
JavaScript) Closure 그는 무엇인가?  (0) 2023.09.13
JavaScript) Promise 와 예제  (0) 2023.09.13