객체(Object)
- 객체는 이름과 값으로 구성된 프로퍼티들의 집합이다.
- {} (중괄호)로 감싸고, 콜론으로 구분된 이름/값의 쌍이 쉼표로 분리된 목록의 형태다.
객체 생성의 규칙
- property 이름은 중복될 수 없다.
- property이름과 property값 사이에 ': (콜론)'으로 구분한다.
- property를 추가할 때는 ', (쉼표)'를 붙여준다.
- property 값에는 어느 type이나 가능하다. (string, number, array, object, function..)
키(key)
- 마치 특정 값을 갖고 있는 변수같은 역할을 한다.
- 해당 키로 프로퍼티에 어떤 값이 저장되어 있는지 알 수 있다.
- 키의 값에는 텍스트, 숫자, 함수, 객체 등 모든 형식을 넣을 수 있다.
let difficult = {
'my name': 'boong',
color: 'silver',
키: '한글인 키는 따옴표가 없어도 되는군!!',
'!키': '느낌표 있는 키는 따옴표가 필요하군',
$special: '$는 없어도 되는군'
};
- 객체의 키에는 스페이스, 한글, 특수문자 등이 들어갈 수 있다.
- 키에 특수문자가 없으면 따옴표를 생략하고 쓸 수 있다.
property 접근
마침표(.) 연산자
- 마침표(.) 연산자를 사용하며, 접근하려는 객체명은 왼쪽에, 프로퍼티 명은 오른쪽에 위치한다.
- 키로 바로 접근할 때 사용한다.
- 따옴표 없이 키를 바로 써준다.
대괄호([]) 연산자
- 대괄호([])를 사용하여, 접근하려는 객체명은 왼쪽에, 프로퍼티 명은 쌍따옴표("")와 함께 대괄호 안에 작성한다.
- 스페이스, 숫자가 포함된 키는 대괄호로 접근한다.
프로퍼티 접근
- 변수에 키 이름이 저장되어 있을 때, 변수로 프로퍼티 접근이 가능하다. (마침표(.) 연산자로는 불가능!)
let name = "키";
console.log(difficult[name]);
console.log(difficult.name);
let plan1 = {
name: "Basic"
};
console.log(plan1.name);
console.log(plan1["name"]);
let plan1 = {
name: "Basic"
};
let propertyName = "name";
console.log(plan1[propertyName]);
property 할당
difficult[name] = '값 바꾼다';
console.log(difficult[name]);
difficult.color = '색깔';
console.log(difficult.color);
console.log('생성전: ' + difficult.new);
difficult.new = '새로 추가된 프로퍼티';
console.log('생성후: ' + difficult.new);
- 키가 존재하는 객체에, 다시 한 번 할당하면 값이 교체(수정)된다.
- 이전에 없던 새로운 키로 접근하면, 새로운 프로퍼티가 추가 된다.
const
로 선언한 변수에 객체를 다시 할당하면 오류가 생기지만, 그 객체에 프로퍼티를 추가하거나 수정하는 것은 가능하다.
const mutableObj = {
name: '객체'
};
mutableObj = {
name: '수정'
}
- 변수(mutableObj) 자체에 객체를 재할당하는 것은 불가능하다.
- 그렇지만 프로퍼티에 접근해서 내용을 수정하거나, 프로퍼티를 추가하는 것은 가능하다.
Method(메서드)
- 객체에 저장된 값이 함수일 때, 메서드라고 부른다.
console.log()'
도 객체의 형태이고, 자바스크립트 어디에서나 접근 가능하므로 global 객체이다.
- console 다음 마침표(.)로 프로퍼티에 접근하고, log라는 키의 값은 함수다. => log는 console이라는 객체의 메서드다.
let methodObj = {
do: function() {
console.log('메서드 정의');
}
}
methodObj.do();
중첩된 객체(Nested Object)
- 프로퍼티 값이 객체일 수도 있고, 프로퍼티 값인 배열의 요소가 객체일 수도 있다.
let nestedObj = {
type: {
year: '2019',
'comment-type': [{
name: 'simple'
}]
}
}
- 'simple'을 출력하고 싶다면? console.log(nestedObj.type['comment-type'][0].name);
- 컴퓨터는 왼쪽에서 오른쪽으로 해석하기 때문에, 왼쪽에 직접 코드를 써야 한다.
객체는 reference로 저장된다
- 객체를 변수에 저장하면 객체 자체가 저장되는 것이 아니라 reference가 저장된다.
- 반대로, 텍스트는 변수에 저장하면 텍스트 자체가 저장된다.
const a = "안녕"
const b = "안녕"
console.log(a===b)
const hiObj = {
name: '안녕'
};
const helloObj = {
name: '안녕'
};
console.log('객체비교 =>', hiObj === helloObj);
- 객체는 변수에 저장할 때, 객체 자체를 그대로 저장하지 않고, 객체가 담긴 어느 메모리의 reference 를 저장한다.
- hiObj 가 갖고 있는 진짜 값은 메모리 주소인 reference이다.
- 하지만 hiObj 를 불러올 때 메모리 주소를 반환하는 것이 아니라, 해당 메모리에 저장된 데이터를 반환해 준다.
- 그래서 눈에 보이는 데이터는 똑같지만, hiObj 와 helloObj 가 갖고 있는 진짜 값은 다르다.
console.log('객체비교 =>', hiObj === helloObj);
console.log('객체값비교 =>', hiObj.name === helloObj.name);
- 그래서 객체를 담은 변수를 비교하면 서로 같지 않다고 나온다.
- 그러나 객체 내부의 프로퍼티 값이 텍스트일 경우는, 텍스트를 비교하게 되어 서로 같음 / 다름 여부를 판단할 수 있다.
const 선언 객체
const mutableObj = {
name: '객체'
};
mutableObj = {
name: '수정'
}
mutableObj.name = '수정 됩니다!';
- const로 선언된 변수는 값이 바뀔 수 없기 때문에 새로운 객체를 할당하며 오류가 난다. 새로운 메모리 주소(reference)로 수정을 시도하기 때문!
- 하지만
mutableObj.name
로 프로퍼티에 접근해서 수정할 수 있다.
저장된 reference가 바뀌는 것이 아니라 객체 내부의 프로퍼티 값이 수정되는 것이기 때문!