원시 값을(string, number, bigint, boolean, undefined, symbol..) 제외한 나머지 값(함수, 배열, 정규 표현식)은 모두 객체입니다!
원시 타입은 딱 하나의 값만을 나타내지만, 객체 타입은 다양한 타입의 값을 하나의 단위로 구성한 자료구조입니다!
var person = {
name : 'Lee',
age : 20
};
객체는 0개 이상의 프로퍼티로 구성된 집합이며, 프로퍼티는 키와 값으로 이루어졌다.
여기서 person
이라는 객체는 name
과 age
라는 프로퍼티로 이뤄져 있고, 이 각각은 프로퍼티 키와 값(value)로 이루어져 있다.
자바스크립트에서는 모든 것이 프로퍼티 값이 될 수 있다. 그렇기 때문에, 함수도 프로퍼티 값으로 사용할 수 있다. 만약, 함수가 프로퍼티 값으로 사용될 때에는 일반 함수와 구분하기 위하여 메서드라고 지칭한다!
이렇게 객체는 프로퍼티와 메서드로 구성된 집합체입니다.
자바스크립트는 클래스 기반 객체지향 언어와는 달리, 프로토타입 기반 객체지향 언어이기 때문에 다양한 객체 생성 방법을 지원한다.
객체 생성 방법 중에 가장 일반적인 것은 객체 리터럴을 사용하는 방법입니다!
var person = {
name : 'Lee',
sayHello : function() {
console.log(`Hello! My name is ${this.name}.`);
}
};
console.log(typeof person); //object
console.log(person); //{name : "Lee", sayHello : f}
이렇게 중괄호를 이용하여 0개 이사의 프로퍼티를 정의합니다. 만약 중괄호 내에 프로퍼티를 정의하지 않으면 빈 객체가 생성됩니다!
객체 리터럴은 값으로 평가되는 표현식입니다. 그래서 객체 리터럴의 닫는 중괄호 뒤에는 세미콜론
을 붙여 주자!
객체 리터럴은 자바스크립트의 유연함, 강력함을 대표하는 객체 생성 방식! 객체를 생성하기 위해서는 숫자 값이나 문자열을 만드는 것과 유사하게 리터럴로 객체를 생성할 수 있네요 :)
객체 생성 방식은 객체 리터럴 외에는 함수를 사용합니다.
만약 객체를 새성할 때, 식별자 네이밍 규칙을 따르지 않는 프로퍼티 키를 사용하면 번거롭다. 아래 예를 보자.
var person = {
firstName : 'Ung-mo',
'last-name' : 'Lee'
};
두번째 프로퍼티가 식별자 네이밍 규칙을 따르고 있지 않다. 그래서 따옴표를 생략할 수 없다..매우 번거로움 ㅜ
그리고 신기한 건, 빈 문자열을 프로퍼티 키로 사용해도 에러가 발생하지는 않는다. 하지만 키로서의 의미는 갖지 못하겠지?
var foo = {
0 : 1,
1 : 2,
2 : 3
};
프로퍼티 키에 이렇게 문자열이나 심벌 값 외의 값을 사용하면, 암묵적 타입 변환을 통하여 문자열이 된다. 내부적으로 문자열로 변환되는 것이다.
그리고 이미 존재하는 프로퍼티 키를 중복 선언하면, 나중에 선언한 프로퍼티가 먼저 선언한 프로퍼티를 덮어쓴다.
var obj = {};
var key = 'Hello';
obj[key] = 'world';
이렇게 대괄호를 이용하여 프로퍼티 키를 동적으로 생성할 수 있습니다.
아래 예제도 가능합니다.
var person = {
name : 'Lee'
};
person.age = 20;
console.log(person);
이렇게 만들어도 가능!
var person = {
'last-name' : 'Lee',
1 : 10
};
person.'last-name'; //SyntaxError
person.last-name; // NaN (브라우저 환경)
person[last-name]; //last is not defined
person['last-name']; //Lee 출력
person.last-name
의 실행 결과는 ReferenceError : name is not defined
이다. 브라우저에서는 NaN이 발생하게 된다. 아래 이유를 조목조목 따져보자.
1. person.last-name
을 평가할 때, 자바스크립트 엔진은 먼저 person.last
를 평가한다. 그런데 이것은 없는 값이니까 undefined
로 평가된다.
2. person.last-name
은 undefined-name
으로 평가된다. 자바스크립트 엔진은 name
이라는 식별자를 찾는다. (여기서 프로퍼티 키가 아니라 식별자로 해석됨에 주의)
3. Node.js에서는 name
이 없으니까 undefined name 에러가 발생하는데, 브라우저 환경에서는 전역 변수(전역 객체 window의 프로퍼티)가 암묵적으로 존재한다. 기본적으로 빈 문자열이므로 브라우저에서는 다음과 같이 해석한다. person.last-name
은 undefined - ''
이니까, NaN이다.
last-name은 이름 규칙을 지키지 않기 때문에 따옴표로 감싸야 합니다 ! 그리고 마침표 표기법은 이름 규칙을 지키지 않은 친구를 용납하지 않는군!
1. 프로퍼티 축약 표현
변수 이름과 프로퍼티 키가 동일할 때에는 프로퍼티 키를 생략할 수 있다.
//ES5
var x = 1, y = 2;
var obj = {
x : x,
y : y
};
//ES6
let x = 1, y = 2;
const obj = { x, y };
2. 계산되는 프로퍼티의 이름
문자열 또는 문자열로 타입 변환할 수 있는 값으로 평가되는 표현식을 사용하여, 프로퍼티 키를 동적으로 생성하고 싶다면 대괄호를 사용하여라!
//ES5
var prefix = 'prop';
var i = 0;
var obj = {};
obj[prefix + '-' + ++i] = i;
obj[prefix + '-' + ++i] = i;
//ES6
const prefix = 'prop';
let i = 0;
const obj = {
[`${prefix} - ${++i}`] : i;
[`${prefix} - ${++i}`] : i;
};
이렇게 대괄호를 사용하여 안에서 프로퍼티 이름 동적 생성할 수 있다!
3. 메서드 축약 표현
function
을 축약하여 표현 가능하다.
//ES5
var obj = {
name : 'Lee',
sayHi : function(){
console.log('Hi! ' + this.name);
}
}
//ES6
const obj = {
name : 'Lee',
sayHi() {
console.log('Hi! ' + this.name);
}
};
이렇게 프로퍼티와 객체에 대해 깊게 공부할 수 있는 시간이었다!