각각의 변수에 값을 일일이 저장하는 대신, 코드관리 및 데이터 관리를 위해 객체(object)를 이용한다.
객체는
- 중괄호({})로 감싸져 있고,
- 콜론으로 구분된 이름/값 쌍들이
- 쉼표로 분리된 목록의 형태이다.
- 즉, 객체는 이름과 값으로 구성된 프로퍼티(property)들의 집합이다.
let plan1 = {
name: "Basic",
price: 3.99,
space: 100,
transfer: 1000,
pages: 10
};
- 프로퍼티 이름은 중복될 수 없다.
- 프로퍼티 이름과 값은 콜론(:)으로 구분된다.
- 프로퍼티 값에는 어느 타입이나 가능하다(string, number, array, object, function)
객체의 프로퍼티에 접근하는 방법은 2가지가 있다.
1. dot(.)
을 이용해서 접근하는 방법 (console.log(plan1.name)
)
2. 대괄호([])를 이용하는 방법 (console.log(plan1["name"])
)
dot으로 접근하는 방법이 가장 간단하지만, key 값에 스페이스가 있거나 key값이 숫자 등이라면 대괄호를 이용해 접근해야 한다.
// plan1 객체의 프로퍼티 name : "Basic"에 접근하고 싶을 때, 꺼내오는 방법
console.log(plan1.name);
console.log(plan1["name"]); // 대괄호([]) 안에는 변수가 들어갈 수 있다.
// 또는
let propertyName = "name";
console.log(plan1[propertyName]);
아래의 객체에서 "HTML Guide"를 꺼내고 싶다면,
let objData = {
name: 50,
address: {
email: "gaebal@gmail.com",
home: "위워크 선릉2호점",
},
books: {
year: [2019, 2018, 2006],
info: [
{
name: "JS Guide",
price: 9000,
},
{
name: "HTML Guide",
price: 19000,
author: "Kim, gae bal",
},
],
},
};
let bookName = objData.books.info[1].name;
console.log(bookName); // HTML Guide
let myObj = {
property1: "hello",
property2: [1, 2, 3, 4, 5],
property3: {
childproperty: "haha",
},
};
let name = "property1";
myObj[name] = ["hi", "hello"]; // 원래 값 "hello"에서 배열 ["hi", "hello"]로 변경
console.log(myObj.property1[0]); // name의 첫번째 요소('hi') 꺼내오기
세 개의 배열을 인자로 받는 함수 getData를 다음 요구사항을 충족하는 객체로 만들어서 return하라.
- 인자
salesArr: 날짜별 판매량
ex) [["20190401", 34], ["20190402", 23], ["20190403", 29]]
reviewArr: 날짜별 리뷰수
ex) [["20190328", 3], ["20190401", 0], ["20190403", 1]]
likeArr: 날짜별 좋아요수
ex) [["20190328", 98], ["20190401", 102], ["20190403", 125]]- 요구사항
objData가 갖고 있는 property는 3개 입니다.
sumAmount: 총 판매량
sumReview: 총 리뷰갯수
sumLike: 총 좋아요수function getData(salesArr,reviewArr,likeArr){ let sumSales = salesArr[0][1]; for (i=1; i < salesArr.length; i++) { sumSales = sumSales + salesArr[i][1]; } let sumReviews = reviewArr[0][1]; for (i=1; i < reviewArr.length; i++) { sumReviews = sumReviews + reviewArr[i][1]; } let sumLikes = likeArr[0][1]; for (i=1; i < likeArr.length; i++) { sumLikes = sumLikes + likeArr[i][1]; } let objData = { sumAmount: sumSales, sumReview: sumReviews, sumLike: sumLikes } return objData }
객체는 다른 데이터 타입처럼 변수에 저장할 수 있으며,
{}
모양으로 생긴 객체를 object literal(객체 리터럴)이라고 한다.
순서가 있는 배열과는 달리 객체는 순서가 없으며 키(key)-값(value) 쌍으로 된 데이터의 모임이고 순서가 뒤바껴도 관계가 없다. 배열처럼 index로 접근하는 것이 아니라 키로 접근하기 때문!
변수에 키 이름이 저장되어 있으면 변수로도 프로퍼티에 접근할 수 있다.
이 때에는 dot(.)으로 접근하지 않고, 항상 대괄호([])
로 접근해야 한다.
let difficult = {
33: '숫자 형식 가능',
'my name': '스페이스 포함 가능',
키: '따옴표 없이 가능',
'!키': '느낌표가 포함되면 따옴표가 필요',
$special: '$는 따옴표가 없어도 가능'
}
let name = `키`; // difficult 객체의 key '키'를 변수에 할당
console.log(difficult[name]); // 변수로 프로퍼티에 접근하기
console.log(difficult.name); // undefined, name은 프로퍼티가 아니기 때문에 dot으로 접근 불가
객체에 이미 키가 존재할 때 다시 한 번 할당하면 값이 수정되며, 새로운 키, 값을 추가할 수도 있다.
difficult[name] = '값 바꾸기';
console.log(difficult[name]); // difficult['키'] 값 변경 : '값 바꾸기'
difficult.newProperty = '새로운 키, 값 추가';
const로 선언된 변수는 값을 절대 수정할 수 없다.
const로 선언된 변수에 객체를 다시 할당하면 오류가 생기지만, 그 객체에 프로퍼티를 추가하거나 수정을 할 수 있다.
const mutableObj = {
name: '객체'
};
mutableObj = {
name: '수정' // 변수 재할당 불가
}
mutableObj.type = 'Object 타입' // 키,값 추가는 가능!
const information = {
name: '김개발'
}
const verb = 'develops'
const project = 'facebook'
// 객체에 verb의 값을 키로, 그 키 값을 project의 값으로 추가하고 싶을때
information[verb] = project;
information.develops = 'facebook' // 이때 키와 값은 항상 develops와 facebook으로 정해져있음.
객체에 저장된 값이 함수일 때 메서드라고 부른다.
let methodObj = {
do: function() {
console.log('메서드 정의는 이렇게');
}
}
methodObj.do(); // methodObj 내 메서드 호출하기.
실무에서 사용되는 대부분의 객체는 거의 중첩되어 있다.
프로퍼티 값이 객체일 수도 있고, 프로퍼티 값인 배열의 요소가 객체일 수도 있다.
let nestedObj = {
type: {
year: '2019',
'comment-type': [
{
name: 'simple'
}
]
}
}
// 'simple' 출력하기
console.log(nestedObj.type['comment-type'][0].name);
객체를 변수에 저장하면 객체 리터럴 자체가 저장되는 것이 아니라 reference(메모리 주소)가 저장된다.
const a = '안녕'; // 변수에 저장된 텍스트는 텍스트 자체로 저장됨.
const b = '안녕';
console.log(a===b); // true, 따라서 같은 텍스트면 true
반면, 객체의 경우 프로퍼티 키, 값이 동일해도 false로 출력됨.
텍스트 자체로 저장되는 것이 아니라 객체가 담긴 어느 메모리의 reference를 저장하기 때문에.
const hiObj = {
name: '안녕'
};
const helloObj = {
name: '안녕'
};
console.log(hiObj === helloObj); // false, 여기서 비교하는 값은 hiObj와 helloObj객체가 담긴 메모리 주소임.
console.log(hiObj.name === helloObj.name); // false
앞서, 객체는 순서가 없고 키를 통해서만 접근해야한다고 했다. 하지만 객체도 순회가 불가능한건 아니다. 다만, 배열과 다르게 순서가 없기때문에 어떤 순서에 따라 객체의 키에 접근하게 될지는 알 수 없다. 따라서 객체의 순회는 순서가 보장되지 않은 순회
라고 부른다.
Object.keys
메소드는 어떤 객체가 가지고 있는 키들의 목록을 배열로 리턴하는 메소드이다. 이 메소드는 객체의 내장 메소드가 아니라 객체 생성자인 Object가 직접 가지고 있는 메소드이다.
const obj = {
name: 'melon',
weight: 4350,
price: 16500,
isFresh: true
}
const keys = Object.keys(obj)
console.log(keys) // ['name', 'weight', 'price', 'isFresh']
여기서 Object.keys
메소드가 리턴하는 값은 배열이기 때문에 이걸로 반복문을 사용할 수 있다!
for (let i =0; i<keys.length; i++) {
const key = keys[i] // 각각의 키, [ 'name', 'weight', 'price', 'isFresh' ]
const value = obj[key] // 각각의 키에 해당하는 값, melon, 4350, 16500, true
console.log(value)
}
ES6에서는
Object.keys
와 유사한Object.values
,Object.entries
가 추가되었다.
Object.values
객체의 값으로 이루어진 배열 리턴
Object.entries
객체의 키와 값의 쌍으로 이루어진 길이 2짜리 배열로 이루어진 배열 리턴.const values = Object.values(obj) console.log(values) // 결과 ['melon', 4350, 16500, true] const entries = Object.entries(obj) console.log(entries) /* 결과(Object.entries가 가장 유용하게 쓰임) entries === [ ['name', 'melon'], ['weight', 4350], ['price', 16500], ['isFresh', true] ] */
2) for-in문
반복문인 for문과 같은 종류의 문법이지만, 객체와 배열을 위해 특별히 존재하는 ES6에서 추가된 문법이다.
기존에 for문에서 사용했던(let i=0; i<arr.length ;i++)
을 축약한 문법이다.
for (let i in arr) { // i를 0으로 초기화하고 배열의 길이와 비교하고 1씩 증가시키는 등의 코드 생략
console.log(i)
console.log(arr[i])
}
예시
const obj = {
name: 'melon',
weight: 4350,
price: 16500,
isFresh: true
}
for (let key in obj){ // 인덱스 대신 객체의 각 키에 해당하는 문자열을 할당받음
const value = obj[key]
console.log(key)
console.log(value)
}