[Modern JS Deep Dive]CH10-객체 리터럴

Boo Sung Jun·2022년 6월 20일
0

JavaScript

목록 보기
2/27
post-thumbnail

Modern JavaScript Deep Dive 스터디 - CH10 체 리터럴

참고 자료: ⟪모던 자바스크립트 Deep Dive⟫"(이웅모 지음,위키북스, 2020)


객체(Object)

  • 0개 이상의 프로퍼티로 구성된 집합 -> 프로퍼티는 키(key)와 값(value)로 구성
  • JavaScript에서 사용할 수 있는 모든 값은 프로퍼티가 될 수 있음
  • 함수(function)를 프로퍼티의 값으로 설정가능 -> 메서드(method)
  • 자바스크립트는 객체(object) 기반의 프로그래밍 언어 -> 원시값(primitive value) 을 제외한 나머지 값(함수, 배열, 정규 표현값...)은 모두 객체
  • 원시값은 변경 불가(immutable) 한 값이지만, 객체는 변경 가능(mutable)
  • 원시 타입은 하나의 값만 나타내지만 객체 타입(object / reference type) 은 다양한 타입의 값(원시 값 또는 다른 객체)을 하나의 단위로 구성

자바스크립트 객체 생성 방법

  1. 객체 리터럴
  2. object 생성자 함수
  3. 생성자 함수
  4. Object.create 메서드
  5. 클래스(ES6)

클래스 기반 객체지향 언어와는 달리 다양한 객체 생성 방법을 지원

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

var person = {
  name: "Wi",
  sayHello: function () {
    console.log(`Hello My name is ${this.name}`);
  },
};
  • 변수에 할당되는 시점에 자바스크립트 엔진은 객체 리터럴을 해석해 객체를 생성
  • 객체 리터럴은 값으로 평가되는 표현식이므로 닫는 중괄호 뒤에 세미콜론을 붙임

프로퍼티(Property)

  • 객체는 프로퍼티의 집합

  • 프로퍼티는 으로 구성

    프로퍼티 키(key): 문자열(string) 또는 심벌(symbol) 값
    프로퍼티 값(value): 자바스크립트에서 사용할 수 있는 모든 값

  • 프로퍼티 키는 프로퍼티 값에 접근할 수 있는 이름으로서 식별자 역할 -> 식별자 네이밍 규칙 존재
    -> 식별자 네이밍 규칙을 준수하는 프로퍼티 키는 따옴표 생략 가능, 식별자 네이밍 규칙을 따르지 않는 이름에는 반드시 따옴표를 사용

var person = {
firstName: "Ung-mo", // 규칙을 준수.
"last-name": "Lee", // 규칙을 준수하지 않음.
};

var person = {
firstName: "Ung-mo", // 규칙을 준수.
last-name: "Lee", // SyntaxError: Unexpected token -
};
  • 프로퍼티 키는 동적으로 생성 가능 <- 프로퍼티 키로 사용할 표현식을 대괄호[]로 묶어야 함
  • 빈 문자열을 프로퍼티 키로 사용해도 에러가 발생하지 않음. But 권장하지 않음
  • 프로퍼티에 문자열이나 심벌 값 외의 값을 사용하면 암묵적 타입 변환 을 통해 문자열로 변경
var foo = {
  0: 1,
  1: 2,
  2: 3,
};

console.log(foo); // { '0': 1, '1': 2, '2': 3 } << 키값이 문자열 형태로 암묵적 타입 변환
  • 이미 존재하는 프로퍼티 키를 중복 선언한 경우, 나중에 선언한 프로퍼티 사용
var foo = {
  name: "abc",
  name: "def",
};

console.log(foo); // { name: 'def' }
  • 프로퍼티 구분할 땐 콤마, 사용. 맨 마지막 프로퍼티 끝에도 콤마, 넣어도 됨(나중에 코드 수정할 때 편하기 때문에 개인적으로 권장 -> prettier에 미리 적용해두면 좋음)
var obj = {
  a: 1,
  b: 2,
  c: 3,
}

프로퍼티 접근

1. 마침표 표기법(dot notation)

  • 마침표. 이용

2. 대괄호 표기법(bracket notation)

  • 대괄호[] 이용
var person = {
  "name": "Boo",
  1: 10,
  "last-name": "Lee",
};

// 1. 마침표 표기법
console.log(person.name); // "Boo"
// 2. 대괄호 표기법
console.log(person["name"]); // "Boo"

// ===== 주의사항 =====
// 환경에 따라 결과 다를 수 있음
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"
person['name']; // Boo
person[name]; // undefined

// 대괄호 표기법에서 숫자 키는 따옴표 생략 가능
person[1]; // 10
person["1"]; // 10

// 마침표 표기법에서는 숫자키, 따옴표 사용 불가
person.1; // SyntaxError: Unexpected number
persn."1"; // SyntaxError: Unexpected string

프로퍼티 값 갱신, 생성, 삭제

  • 이미 존재하는 프로퍼티에 값을 할당하면 프로퍼티 값이 갱신
  • 존재하지 않는 프로퍼티에 값을 할당하면 프로퍼티가 동적으로 생성
  • delete 연산자로 객체의 프로퍼티를 삭제 가능
  • delete 연산자의 피연산자는 프로퍼티 값에 접근할 수 있는 표현식
  • 존재하지 않는 프로퍼티를 삭제해도 에러가 발생하지 않음
var person = {
  name: "Boo",
};

person.age = 25; // 프로퍼티 동적 생성
console.log(person); // { name: 'Boo', age: 25 }

delete person.age; // 프로퍼티 삭제
delete person.job; // 존재하지 않는 프로퍼티 삭제 -> 에러 발생 X

console.log(person); // { name: 'Boo' }

메서드(method)

  • 자바스크립트에서 함수는 일급 객체 -> 프로퍼티 값으로 사용 가능
  • 일반 함수와 구별 위해 메서드라고 호칭
  • 메서드 내부에서 사용한 this 키워드는 객체 자신을 가리키는 참조 변수
var person = {
  // 프로퍼티
  name: "WI",

  // 메서드
  sayHello: function () {
    console.log(`Hello My name is ${this.name}`);
  },
};

person.sayHello(); // Hello My name is WI

ES6 객체 리터럴 확장 기능

1. 프로퍼티 축약 표현(property shorthand)

  • 프로퍼티 값으로 변수를 사용할 때, 프로퍼티 키를 생략 -> 변수 이름과 동일한 이름으로 프로퍼티 키 생성
// ES6
let x = 1, y = 2;

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

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

// ES5
var x = 1, y = 2;

var obj = {
  x: x,
  y: y
};

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

2. 계산된 프로퍼티 이름(computed property name)

  • 문자열 또는 문자열로 타입 변환할 수 있는 값으로 평가되는 표현식을 사용해 프로퍼티 키를 동적으로 생성 가능
  • 프로퍼티 키로 사용할 표현식을 대괄호[]로 묶어서 사용
// 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}

// ES5
// ES5에서 계산된 프로퍼티 이름으로 프로퍼티 키를 동적 생성 하려면 객체 리터럴 외부에서 대괄호 표기법을 사용
var prefix = 'prop';
var i = 0;

var obj = {};

// 계산된 프로퍼티 이름으로 프로퍼티 키 동적 생성
obj[prefix + '-' + ++i] = i;
obj[prefix + '-' + ++i] = i;
obj[prefix + '-' + ++i] = i;

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

3. 메서드 축약 표현

  • function 키워드를 생략한 메서드 정의 방식
// ES6
const obj = {
  name: 'Lee',
  // 메서드 축약 표현
  sayHi() {
    console.log('Hi! ' + this.name);
  }
};

obj.sayHi(); // Hi! Lee

// ES5
var obj = {
  name: 'Lee',
  sayHi: function() {
    console.log('Hi! ' + this.name);
  }
};

obj.sayHi(); // Hi! Lee
  • 메서드 축약 표현으로 정의한 메서드는 프로퍼티에 할당한 함수와 다르게 동작 -> constructor X, Prototype 프로퍼티가 없음(26.2장 참조)
const obj = {
  x: 1,
  // foo는 메서드
  foo() { return this.x; },
  // bar에 바인딩된 함수는 메서드가 아닌 일반 함수
  bar: function() { return this.x; }
};

// foo, bar 둘 다 callable
console.log(obj.foo()); // 1
console.log(obj.bar()); // 1

// foo는 prototype 프로퍼티가 없음
new obj.foo(); // -> TypeError: obj.foo is not a constructor
new obj.bar(); // -> bar {}

0개의 댓글