객체는 오직 하나의 데이터(문자열, 숫자 등)만 담을 수 있는 원시 자료형과는 달리 다양한 데이터를 담을 수 있다. 키로 구분된 데이터 집합 혹은 복잡한 개체를 저장할 수 있다.
객체는 중괄호 {…} 를 이용해 만들 수 있다. 중괄호 안에는 키(key) : 값(value) 쌍으로 구성된 프로퍼티를 여러 개 넣을 수 있는데, 키엔 문자형, 값엔 모든 자료형이 허용된다. 프로퍼티 키는 프로퍼티 이름이라고도 불린다.
빈 객체를 만드는 방법
let user = new Object(); // 객체 생성자 문법
let user = {}; // 객체 리터럴 문법
중괄호 {…} 를 이용해 객체를 선언하는 것을 객체 리터럴이라고 부른다.
객체를 선언할 때는 주로 이 방법을 이용한다.
리터럴과 프로퍼티
중괄호 {…} 안에는 ‘키:값’ 쌍으로 구성된 프로퍼티가 들어간다.
콜론을 기준으로 왼쪽에는 키, 오른쪽엔 값이 위치한다.
let user = {
name : 'john',
age : 30
};
점 표기법을 이용하면 프로퍼티 값을 읽을 수 있다.
alert( [user.name](<http://user.name>) );
프로퍼티 값에는 모든 자료형이 올 수 있다. 불린형 프로퍼티를 추가하는 방법은 다음과 같다.
user.isAdmin = true ;
delete 연산자를 이용하면 프로퍼티를 삭제할 수 있다.
delete user.age ;
여러 단어를 조합해 프로퍼티 이름을 만든 경우에는 프로퍼티 이름을 따옴표로 묶어야 한다.
let user = {
name : 'John',
age : 30,
"likes birds" : true
};
이 경우, 점 표기법을 사용하여 프로퍼티 값을 읽을 수 없다.
점은 키가 유효한 변수 식별자인 경우에만 사용할 수 있다.
유효한 변수 식별자에는 공백이 없어야 하고, 숫자로 시작하지 않아야 하며, $와 _를 제외한 특수 문자가 없어야 한다.
키가 유효한 변수 식별자가 아닌 경우에는 점 표기법 대신 대괄호 표기법을 사용한다. 이는 키에 어떤 문자열이 있든 상관없이 동작한다.
let user = {}; // 객체 리터럴
// set
user["likes birds"] = true;
//get
alert( user["likes birds"] );
//delete
delete user["likes birds"];
대괄호 표기법에서는 점 표기법과는 달리 문자열을 사용할 때는 문자열을 따옴표로 묶어 줘야 한다는 점에서 주의가 필요하다. (따옴표 종류는 상관 없다.)
대괄호 표기법을 사용하면 변수를 키로 사용한 것과 같이 문자열뿐만 아니라 모든 표현식의 평가 결과를 프로퍼티 키로 사용할 수 있다.
let key = "likes birds";
user[key] = true;
변수 key는 런타임에 평가되기 때문에 사용자 입력값 변경 등에 따라 값이 변경될 수 있다. 평가가 끝난 후의 결과가 프로퍼티 키로 사용되기 때문에 이를 응용하면 코드를 유연하게 작성할 수 있다. 점 표기법은 이와 같은 방식을 사용할 수 없다.
let user = {
name: 'John',
age : 30
};
let key = prompt("사용자의 어떤 정보를 얻고 싶으신가요?", "name"); // 문자열을 반환한다.
alert( user[key] );
계산된 프로퍼티
객체를 만들 때 객체 리터럴 안의 프로퍼티 키가 대괄호로 둘러싸여 있는 경우, 이를 계산된 프로퍼티라고 부른다.
let fruit = prompt("어떤 과일을 구매하시겠습니까?", "apple");
let bag = {
[fruit]: 5, // 변수 fruit에서 프로퍼티 이름을 동적으로 받아 온다.
};
alert( bag.apple );
위 예시에서 [fruit]는 프로퍼티 이름을 변수 fruit에서 가져오겠다는 것을 의미한다.
단축 프로퍼티
실무에서는 프로퍼티 값을 기존 변수에서 받아와 사용하는 경우가 종종 있다.
function makeUser(name, age) {
return {
name: name,
age: age,
};
}
let user = makeUser("John", 30);
alert(user.name);
위 예시의 프로퍼티들은 키와 값의 이름이 매개변수의 이름과 동일하다.
이와 같이 변수를 사용해 프로퍼티를 만드는 경우는 아주 흔한데,
프로퍼티 값 단축 구문을 이용하면 코드를 짧게 줄일 수 있다.
name: name, 대신 name 만 적어 주어도 프로퍼티를 설정할 수 있다.
function makeUser(name, age) {
return {
name,
age,
};
}
‘in’ 연산자로 프로퍼티 존재 여부 확인하기
자바스크립트 객체의 중요한 특징 중 하나는 다른 언어와는 달리, 존재하지 않는 프로퍼티에 접근하려 해도 에러가 발생하지 않고 undefined를 반환한다는 것이다.
이런 특징을 응용하면 프로퍼티 존재 여부를 쉽게 확인할 수 있다.
let user = { name: 'John', age: 30 };
alert( "age" in user);
alert( "laaka" in user);
‘in’ 왼쪽에는 반드시 프로퍼티 이름이 와야 한다. 프로퍼티 이름은 보통 따옴표로 감싼 문자열이 온다.
for…in 반복문
for…in 반복문을 사용하면 객체의 모든 키를 순회할 수 있다.
for (key in object) {}
객체 정렬 방식
객체는 특별한 방식으로 정렬된다.
정수 프로퍼티는 자동으로 정렬되고, 그 외에 프로퍼티들은 객체에 추가된 순서 그대로 정렬된다.
정수 프로퍼티란 변형 없이 정수에서 왔다 갔다 할 수 있는 문자열을 의미한다.
문자열 “49”는 정수로 변환하거나 변환한 정수를 다시 문자열로 바꿔도 변형이 없기 때문에 정수 프로퍼티이다. 하지만 “+49”와 “1.2”는 정수 프로퍼티가 아니다.
객체와 원시 타입 자료형의 근본적인 차이 중 하나는 객체는 참조에 의해 저장되고 복사된다는 것이다. 변수에 객체를 저장할 때, 객체의 동작 방식은 원시 타입과 다르다. 변수에는 객체가 저장되어 있는 메모리 주소인 객체에 대한 참조 값이 저장된다.
let user = { name: “John” };
다음과 같이 변수에 객체를 담을 때, 객체는 메모리 내 어딘가에 저장되고 변수 user에는 객체를 참조할 수 있는 값이 저장된다. 따라서 객체가 할당된 변수를 복사할 때에는 객체의 참조 값이 복사되고 객체는 복사되지 않는다.
let admin = user;
와 같이 코드를 작성하면 변수는 user, admin 두 개이지만 각 변수에는 동일 객체에 대한 참조 값이 저장되는 것이다. 따라서 객체에 접근하거나 객체를 조작할 때는 여러 변수를 사용할 수 있다.
참조에 의한 비교
객체 비교 시 동등 연산자 == 와 일치 연산자 === 는 동일하게 동작한다.
비교 시 피연산자인 두 객체가 동일한 객체인 경우에 참을 반환한다.
let a = {};
let b = a;
alert( a == b );
alert( a === b ); // 둘 다 true. 두 변수는 같은 객체를 참조한다.
let c = {};
let d = {};
alert(c == d ); // false. 두 객체는 독립된 객체이므로 거짓이 반환한다.
객체 복사, 병합과 Object.assign
중첩 객체 복사
<aside> 💡
</aside>