10장 객체 리터럴


객체란?

자바스크립트 구성하는 모든 것이 객체임.
원시값 빼고 나머지 ( 함수, 배열, 정규 표현식 등) 모든게 객체라고 보면 됨.
원시값은 변경불가능 <-> 객체는 변경가능 (10장 객체 리터럴 참고)
즉, 객체는 프로퍼티와 메서드로 구성된 집합체이다

프로퍼티와 메서드

객체 리터럴에 의한 객체 생성

일반적인 클래스 기반 객체지향 언어의 객체 생성

  1. 클래스를 사전에 정의
  2. 필요한 시점에 new 연산자와 함께 생성자(constructor) 호출
  3. 인스턴스 생성

자바스크립트의 객체 생성 방법은 다양함 : 프로토타입 기반 객체지향 언어


프로퍼티

문자열 or 문자열로 평가할 수 있는 표현식으로 프로퍼티 키 동적으로 생성가능.

var obj = {};
var key = 'hello';

// ES5: 프로퍼티 키 동적 생성
obj[key] = 'world';
// ES6: 계산된 프로퍼티 이름
// var obj = { [key]: 'world' };

console.log(obj); // {hello: "world"}

여기서 변수 key 값을 바꿔도 obj 프러퍼티의 이름이 바뀌진 않더라.

프로퍼티 접근

마침표로 프로퍼티 접근. 마침표 표기법
대괄호로 프로퍼티 접근. 대괄호 표기법

대괄호안에 문자열 따옴표로 감싸야함. 감싸지 않으면 식별자로 인식
→ 대신 동적으로 프로퍼티에 접근 가능

var person = {
  name: 'Lee'
};
var find="name";
// 대괄호 표기법을 이용한 동적 접근
console.log(person[find]); // Lee
var person = {
  'last-name': 'Lee',
  1: 10
};

person.'last-name';  // -> SyntaxError: Unexpected string
person.last-name;    // -> 브라우저 환경: NaN
                     // -> Node.js 환경: ReferenceError: name is not defined
person[last-name];   // -> ReferenceError: last is not defined
person['last-name']; // -> Lee
왜 브라우저랑 node.js 환경에서의 결과 값이 다를까

last-name 이 따로따로 평가되는데, last 식별자 없어서 다음으로 name 식별자를 전역변수에서 찾는 거임. 근데 브라우저에는 전역객체 window 에 name 프로퍼티가 있음. 그래서 결과값이 달라짐.
➕ 브라우저는 전역객체 window 위? 안에서 동작한다.

프로퍼티 키가 숫자로 이뤄진 문자열인 경우 따옴표를 생략할 수 있다.

person.1;     // -> SyntaxError: Unexpected number
person.'1';   // -> SyntaxError: Unexpected string
person[1];    // -> 10 : person[1] -> person['1']
person['1'];  // -> 10

프로퍼티 갱신, 동적 생성, 삭제

var person = {
  name: 'Lee'
};
// person 객체에 name 프로퍼티가 존재하므로 name 프로퍼티의 값이 갱신된다.
person.name = 'Kim';
console.log(person);  // {name: "Kim"}

// person 객체에는 age 프로퍼티가 존재하지 않는다.
// 따라서 person 객체에 age 프로퍼티가 동적으로 생성되고 값이 할당된다.
person.age = 20;
console.log(person); // {name: "Lee", age: 20}

// person 객체에 age 프로퍼티가 존재한다.
// 따라서 delete 연산자로 age 프로퍼티를 삭제할 수 있다.
delete person.age;
// person 객체에 address 프로퍼티가 존재하지 않는다.
// 따라서 delete 연산자로 address 프로퍼티를 삭제할 수 없다. 이때 에러가 발생하지 않는다.
delete person.address;

console.log(person); // {name: "Lee"}

ES6 객체 리터럴 신기능

프로퍼티 축약 표현

// ES6
let x = 1, y = 2;

// 프로퍼티 축약 표현
const obj = { x, y };

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

계산된 프로퍼티 이름

// ES6
const prefix = 'prop';
let i = 0;

// 객체 리터럴 내부에서 계산된 프로퍼티 이름으로 프로퍼티 키 동적 생성
const obj = {
  [`${prefix}-${++i}`]: i,
  [`${prefix}-${++i}`]: i,
  [`${prefix}-${++i}`]: i
};

console.log(obj); // {prop-1: 1, prop-2: 2, prop-3: 3}

메서드 축약 표현

// ES6
const obj = {
  name: 'Lee',
  // 메서드 축약 표현
  sayHi() {
    console.log('Hi! ' + this.name);
  }
};

obj.sayHi(); // Hi! Lee

축약표현으로 정의한 메서드는 프로퍼티에 할당한 함수와 다르게 동작한다고 한다. 26장 ES6 함수의 추가 기능 참고

reference