[JS] 5. 객체 리터럴

Joo·2024년 6월 18일
0

JavaScript

목록 보기
6/7
post-thumbnail

1. 객체란?

JS는 객체 지향 프로그래밍 언어로 원시 타입을 제외한 거의 모든 것이 객체로 이루어져 있다. 그만큼 객체가 무엇인지 이해하는 것은 JS를 이해하는데 중요한 역할을 한다.

객체는 다양한 데이터 타입의 값을 하나의 구성체로 정의한 복합적인 자료구조이다. 객체 안에는 0개 이상의 프로퍼티의 구성원 집합으로 이루어져 있다. 이때, 프로퍼티의 값에는 모든 값이 올 수 있으므로 원시값, 객체, 함수 등이 올 수 있다.

1.1 객체의 특징

원시 타입과 객체 타입의 차이점은 값을 변경 할 수 있는가 이다.
원시 타입 데이터는 immutable 한 값으로 값을 변경할 수 없다.
하지만 객체 타입 데이터는 mutable 한 값으로 값을 변경할 수 있다.

1.2 프로퍼티

프로퍼티는 키-값의 쌍으로 이루어져 객체를 구성하고 있는 하나의 구성원이다.

프로퍼티의 키에는 string, symbol 값이 올 수 있다.
또한, 프로퍼티의 값에는 모든 타입의 값이 올 수 있으므로 값으로 평가되는 표현식 또한 가능하다.

또한 프로퍼티를 나열할 때는 , 로 구분한다.

1.3 메서드

메서드는 함수가 객체의 프로퍼티 값으로 사용되었을 때 기존 함수와 구분한 명칭이다.
즉, 아래 코드에서 sayHello 의 값을 메서드라고 부른다.

var person = {
	name: 'joo',
	sayHello: function() {
    	console.log(`Hi, ${this.name}!`); // Hi, joo!
    }
};

여기서 메서드 내부의 thisperson 이라는 객체를 가리킨다.
따라서 메서드는 프로퍼티의 상태값을 참조해 사용하거나 조작할 수 있는 동작의 역할을 한다.

객체가 프로퍼티와 메서드를 모두 가질 수 있기 때문에 상태와 동작을 하나의 단위로 구조화할 수 있어 객체 지향 프로그래밍을 구성하고 사용하는데 중요한 역할을 한다.

2. 객체 리터럴로 생성하기

객체를 생성하는데는 5가지의 방법이 있다.

  • 객체 리터럴
  • Object 생성자 함수
  • 생성자 함수
  • Object.create 매서드
  • 클래스

하지만 객체 리터럴 외의 다른 방법들은 함수로 생성한다. 이번에는 객체 리터럴 을 사용한 방법에 대해서 더 알아보자.

기본적으로 객체 리터럴로 객체를 생성하는 것은 {} 중괄호 기호를 사용하는 것이다.

var person = {
	name: 'joo',
	sayHello: function() {
    	console.log(`Hi, ${this.name}!`); // Hi, joo!
    }
};

위의 코드처럼 {} 내부에 0개 이상의 프로퍼티를 정의하면 된다. 또한 변수에 할당되는 시점인 런타임 때, JS엔진은 객체 리터럴을 해석해서 객체를 생성한다.

프로퍼티가 없을 때는 빈 객체를 생성할 수 있다.

var empty = {}; // {}

console.log(typeof empty); // obejct

2.1 객체 리터럴로 생성한 객체의 특징

앞서 person 이라는 객체를 생성했을 때, {} 뒤에 ; 이 있는 것을 확인할 수 있다. 그 이유는 객체 리터럴이 if문, for문과 같은 명령문의 코드 블럭이 아닌 하나의 값이기 때문에 {} 가 종결의 의미를 갖지 않기 때문이다.

2.1.1 프로퍼티 동적 생성

존재하지 않은 프로퍼티를 객체 리터럴 외부에서 프로퍼티를 동적으로 생성할 수 있다.

var person = {
	name: 'joo'
};

person.age = 11; // age 프로퍼티 추가

console.log(person); // { name: 'joo', age: 11 }

2.1.2 프로퍼티 값 갱신

객체에 이미 존재하는 프로퍼티에 중복으로 새로운 프로퍼티 값을 할당하게 되면 기존의 값이 갱신된다.

var person = {
  	name: 'joo',
  	age: 11
};

person.age = 5;

console.log(person); // { name: 'joo', age: 5 }

2.1.3 프로퍼티 삭제

존재하는 프로퍼티를 delete 연산자를 사용해 삭제할 수 있다.
만약 존재하지 않은 프로퍼티를 삭제하는 경우 에러 없이 무시된다.

var person = {
	name: 'joo',
  	age: 11
};

delete person.age; // age 프로퍼티 삭제
delete person.no; // no 프로퍼티는 존재하지 않으므로 삭제 X

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

3. 프로퍼티 규칙

3.1 프로퍼티 키의 규칙

프로퍼티 키에는 string 이거나 symbol 2가지 데이터 타입이 올 수 있다. 그런데 위의 예시 코드들을 보면 그냥 name , age 로 쓴 것을 볼 수 있다.

만약 키가 식별자 네이밍 규칙을 만족한다면 '' ,"" 을 사용하지 않아도 된다. 하지만 그렇지 않을 경우 '', "" 을 사용하지 않으면 에러가 발생한다.

var person = {
	name: 'joo',
  	age: 11,
  	best-friend: 'john' // SyntaxError: Unexpected token '-'
}

var person = {
	name: 'joo',
  	age: 11,
  	'best-friend': 'john'
  	-------- 또는 ---------
  	bestFriend: 'john'
}

위의 에러는 JS가 - 연산자가 있는 표현식으로 해석해 발생하였다.

따라서 식별자 네이밍 규칙을 따르지 않는 이름은 반드시 따옴표가 필요하다

키에는 문자열로 평가될 수 있는 모든 값이 가능하기 때문에 표현식으로 키를 동적 생성할 수 있다.

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

obj[key] = 'value';

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

빈 문자열도 키 이름이 될 수 있지만 의미를 갖지 않으므로 좋지 않다.

var obj = {
	'': ''
};

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

프로퍼티 키에 문자열이나 심볼 값이 아닌 값을 쓰면 암묵적인 타입 변환이 이루어진다.

var obj = {
	0: 0,
  	null: 1,
  	undefined: 2
};

console.log(obj); // { 0: 0, null: 1, undefined: 2 }

하지만 var, function, null과 같은 예약어나 다른 타입의 명칭을 사용하는 것은 좋지 않다.

3.2 프로퍼티 접근

프로퍼티 값에 접근하기 위한 두 가지 방법이 있다.
. 마침표를 사용한 접근 연산자, [] 대괄호를 사용한 접근 연산자 표기법이다.

var obj = {
	a: 1,
    b: 2
};

console.log(obj.a); // 1

console.log(obj['b']); // 2

식별자 네이밍 규칙에 따라 이름을 지은 키는 . 마침표를 사용한 접근 연산자를 사용할 수 있지만 그렇지 않다면 [] 대괄호 접근 연산자 안에 해당 키 값을 따옴표로 감싼 문자열로 사용해야만 접근할 수 있다.

var obj = {
	'a-b': 1,
  	c: 'hi'
};

console.log(obj.a-b); // ReferenceError : b is not defined

console.log(obj['a-b']); // 1

console.log(obj[c]); // ReferenceError : c is not defined

위의 코드에서 첫번째 출력 결과가 NaN 이 나오는 이유는 먼저 obj.a 로 해석해 obj 의 객체에 있는 a 키에 대한 값을 가져오려고 하기 때문이다. 하지만 a 프로퍼티가 존재하지 않아서 undefined 로 반환이 될 것이고, - 연산자 뒤의 b 식별자를 가져오려고 하니 정의된 변수가 아니므로 참조 에러를 발생시킨다.

var person = {
	'my-name': 'joo',
  	age: 11
};

// 브라우저에서 실행할 때
console.log(person.my-name); // NaN

// Node.js에서 실행할 때
console.log(person.my-name); // ReferenceError : name is not defined

위 코드에서 브라우저와 Node.js 환경에서 각각 실행할 때 에러가 다른 이유가 무엇일까?

먼저 브라우저에서 실행하게 되면 name 이라는 값이 '' 빈 문자열로 출력되는데 그 이유는 브라우저의 전역 객체 window 가 갖는 name 프로퍼티가 존재하기 때문이다.
따라서 person.my 프로퍼티가 존재하지 않아 undefined 로 반환되고 식별자 name 의 값이 빈 문자열이므로 undefined - 0 의 결과는 NaN 이다.

profile
한 줄이 모여 책이 되듯 기록하기

0개의 댓글