[모던 자바스크립트 Deep Dive] 10장

Gyuwon Lee·2022년 7월 22일
0
post-thumbnail

42 서울의 모던 자바스크립트 Deep Dive 스터디 학습의 일환으로, 새롭게 알게 된 내용 중심으로 정리되어 있습니다.


CH10. 객체 리터럴

1) 객체란?

객체 란, 프로퍼티메서드 로 구성된 집합체다.

var counter = {
  num: 0, // 프로퍼티
  increase: function() { // 메서드
    this.num++;
  }
};
  • 프로퍼티 : 객체의 상태를 나타내는 값 (데이터)
  • 메서드 : 프로퍼티 (상태, 데이터) 를 참조하고 조작할 수 있는 동작

따라서 이 객체 타입이란, 객체의 상태를 나타내는 값(프로퍼티)과 프로퍼티를 참조 및 조작할 수 있는 동작(메서드)를 모두 포함할 수 있기 때문에, 상태와 동작을 하나의 단위로 구조화할 수 있어 유용하다.

또한 객체는 원시 타입의 값과 달리 변경 가능한 값이다.


2) 객체 생성하기 : 객체 리터럴

자바스크립트는 프로토타입 기반 객체지향 언어로서, C나 JAVA같은 클래스 기반 객체지향 언어와는 달리, 객체 생성 방법에 여러 가지가 지원된다.

  • 객체 리터럴
  • Object 생성자 함수, Object.create 메서드
  • 생성자 함수
  • 클래스(ES6)

이러한 객체 생성 방법들 중에서 가장 일반적이고 간단한 방법은 객체 리터럴을 사용하는 방법이다.

앞서 리터럴 이란 각종 숫자나 연산자, 기호 등 프로그래머가 이해할 수 있는 언어로 작성된 코드라고 설명한 바 있다. 즉 객체 리터럴을 사용한다는 말은 객체를 표현하기 위해 약속되어 있는 기호를 사용하여 객체 자료형을 생성하고, 표기한다는 뜻이다.

let profile = {
  first: 'Jane',
  last: 'Doe',
  age: 20,
  sayHello: function() {
    console.log(`Hello, my name is ${this.first} ${this.last}.`)  
  }
};

profile.sayHello();

객체 리터럴은 중괄호 {} 내에 0개 이상의 프로퍼티를 정의한다. 즉 아무 프로퍼티 없이 빈 객체도 생성할 수 있다.

이때, 객체 리터럴의 중괄호는 코드블록을 의미하지 않는다는 데 주의해야 한다. 코드블록의 닫는 중괄호는, 스스로 자체 종결성을 가지므로 세미콜론이 필요하지 않다. 하지만 객체 리터럴은 값으로 평가되는 표현식 이다. 따라서 객체 리터럴의 닫는 중괄호 뒤에는 세미콜론을 붙인다.

객체 리터럴의 장점?

예를 들어 C 같은 언어에서는, 객체를 생성하기 위해 먼저 자료형 선언이 필요하다. 객체 안에 들어갈 데이터 타입과 이름을 먼저 정의해야 이후에 해당 객체의 인스턴스를 생성해서 사용할 수 있다.

하지만 자바스크립트에서는 이처럼 클래스를 먼저 정의하고 new 연산자와 함께 생성자를 호출하는 등의 과정이 필요하지 않다. 객체 리터럴에 프로퍼티를 포함시켜, 객체를 생성함과 동시에 프로퍼티를 만들 수도 있다. 또, 객체를 생성한 이후에 프로퍼티를 동적으로 추가할 수도 있다.


3) 프로퍼티와 메서드

프로퍼티는 객체를 구성하는 모든 속성들이다. 그 중 함수 자료형인 프로퍼티들은 메서드 라는 이름으로 구분한다.

프로퍼티는 으로 구성된다.

  • 프로퍼티 키: 빈 문자열을 포함하는 모든 문자열 또는 심벌 값
  • 프로퍼티 값: 자바스크립트에서 사용할 수 있는 모든

식별자 네이밍 규칙 (예를 들어, 이름의 맨 앞에는 $, _ 를 제외한 모든 특수문자 및 숫자가 올 수 없다는 것) 을 준수하는 프로퍼티 키는, 문자열이지만 따옴표를 생략하고 사용할 수 있다. 반대로, 규칙을 따르지 않는 키는 반드시 따옴표로 감싸 사용해야 한다.

프로퍼티 동적으로 생성하기

let obj = {};
key = 'hello'
obj[key] = 'value'

console.log(obj); // { hello: 'value' }

obj[hello] = 'world'
console.log(obj); // { hello: 'world' }

문자열 또는 문자열로 평가할 수 있는 표현식대괄호로 묶어, 프로퍼티 키를 동적으로 생성할 수도 있다. 따라서 위처럼 hello 라는 문자열로 평가되는 변수 key 를 넣을 수도, 그냥 문자열 hello 를 (네이밍 규칙을 지켰으므로 따옴표 생략) 넣을 수도 있다.

이 때, 이미 존재하는 프로퍼티 키를 중복 선언하면 나중에 선언한 프로퍼티 값( world )이 먼저 선언한 프로퍼티 값( value )을 덮어쓰며, 에러를 뱉지 않는다는 점에 주의해야 한다.

다른 방식으로는 그냥 존재하지 않는 프로퍼티에 값을 할당하는 방법이 있다.

let profile = {
	first: 'Jane',
};

profile.last = 'Doe';
console.log(profile); // {first : 'name', last : 'Doe'}

메서드

프로퍼티의 값이 함수일 경우 일반 함수와 구분하기 위해 메서드 라고 부른다. 메서드는 객체에 묶여 있는 함수이기 때문이다. 즉 this 키워드를 사용해서 객체 내부에서 사용되는 값(프로퍼티)을 참조 및 조작할 수 있다.


4) 프로퍼티 접근과 삭제

프로퍼티에 접근하기 위해서는 프로퍼티 접근 연산자를 사용하는데, 이는 마침표대괄호 접근 연산자의 두 가지로 나뉜다.

대괄호 접근 연산자

대괄호 접근 연산자를 사용하는 경우, 대괄호 연산자 내부에 지정하는 프로퍼티 키는 반드시 따옴표로 감싼 문자열이어야 한다. 따옴표로 감싸지 않은 이름은 식별자, 즉 할당된 어떤 값을 가리키는 이름으로 본다.

let person = {
  name: 'lee',
};

console.log(person[name]) // ReferenceError: name is not defined

위 예제에서, 의도한 바는 객체 personname 프로퍼티에 접근하는 것이다. 하지만 대괄호 안에 따옴표를 사용하지 않았으므로 엔진은 식별자 name 을 평가해서 생성되거나 참조하고 있는 값을 얻으려 한다. 하지만 name 이 선언되어 있지 않으므로 ReferenceError 가 발생한다.

한편, 식별자 네이밍 규칙을 준수하지 않은 이름의 프로퍼티 키는 반드시 대괄호 연산자를 사용해서 접근해야만 한다.

프로퍼티 삭제

delete 연산자를 사용한다.


5) 객체 리터럴의 확장 (feat.ES6)

(1) 프로퍼티 축약 표현

ES6에서는 프로퍼티 값으로 변수를 사용하는 경우, 변수 이름과 프로퍼티 키가 동일한 이름일 때 프로퍼티 키를 생략할 수 있다. 이 때 프로퍼티 키는 변수 이름으로 자동 생성된다.

let x = 1;
let y = 2;

let obj = {x, y};
console.log(obj); // {x : 1, y : 2}

간단히 생각해서, x = 1 같은 변수 할당문을 x : 1 과 같이 바로 객체의 프로퍼티로 집어넣을 수 있고, 이 때 변수의 이름을 사용한다고 이해했다.

(2) 계산된 프로퍼티 이름

let prefix = 'prop';
let i = 0;

let obj = {
  [prefix + ++i]: i,
  [prefix + ++i]: i,
  [prefix + ++i]: i,
};

console.log(obj); // {prop1 : 1, prop2 : 2, prop3 : 3}

객체 리터럴 내부에서, 프로퍼티 키 자리에 표현식을 넣어 계산된 프로퍼티 이름으로 프로퍼티 키를 동적 생성할 수 있다.

(3) 메서드 축약 표현

ES6으로 넘어오면서, 메서드를 정의하는 방식에 축약 표현 이 추가되었다:

let obj = {
  name : 'Jane',
  
  // 프로퍼티에 할당한 함수
  sayHi : function () {console.log('Hi' + this.name);},
  
  // 메서드 축약 표현
  sayBye() {console.log('Bye' + this.name);},

이렇게 축약 표현으로 정의한 메서드는 프로퍼티에 할당한 함수와 다르게 동작한다.

profile
하루가 모여 역사가 된다

0개의 댓글