이번시간에는 자바스크립트의 자료구조와 자료형에대해 알아보는 시간을 가져보겠습니다.
개별 자료 구조에서 한발 뒤로 물러나서 순회(iteration)에 관해 이야기를 나누고자 합니다.
자바스크립트에서 순회에 필요한 메서드로는 map.keys(), map.values(), map.entries()에 대해 알아봅시다.
이 메서드는 포괄적인 용도로 만들어졌기 때문에 메서드를 적용할 자료구조는 일련의 합의를 준수해야 합니다.
커스텀 자료구조를 대상으로 순회를 해야 한다면 이 메서드들은 쓰지 못하고 직접 메서드를 구현해야 합니다.
keys(), values(), entries()를 사용할 수 있는 구조는 다음과 같습니다.
- Map 함수
- Set 함수
- Array 함수
일반 객체에서도 순회 관련 메서드가 존재하는데, keys(), values(), entries() 와는 문법에 차이가 존재합니다.
Object.keys, values, entries
일반 객체에서는 다음과 같은 메서드를 사용할 수 있습니다.
- Object.keys(obj) - 객체의 키만 담을 배열을 반환
- Object.values(obj) - 객체의 값만 담은 배열을 반환
- Object.entries(obj) - [키,값] 쌍을 담은 배열을 반환
Map, Set, Array 전용 메서드와 일반 객체용 메서드의 차이를 맵을 기준해서 비교한다면 다음과 같습니다.
맵 | 객체 | |
호출문법 | map.keys() | Object.keys(obj) (obj.keys() 가 아님) |
반환 값 | iterable 객체 | '진짜' 배열 |
첫번째 차이는 obj.keys()가 아닌 Object.keys(obj)를 호출한다는 점입니다.
이렇게 문법이 다른 이유는 유연성 때문입니다. 자바스크립트에서는 복잡한 자료구조 전체가 객체에 기반합니다.
그러다 보니까 객체 data에 자체적으로 data.values()라는 메서드를 구현해 사용하는 경우가 있을 수 있습니다.
이렇게 커스텀 메서드를 구현한 상태라도 Object.values(data)같은 형태로 메서드를 호출할 수 있으면 커스텀 메서드와
내장 메서드 둘 다를 사용할 수 있습니다.
두번째 차이로는 메서드 Object.*를 호출하면 iterable 객체가 아닌 객체의 한 종류인 배열을 반환한다는 점입니다.
'진짜'배열을 반환하는 이유는 하위 호환성 때문입니다.
let user = {
name: "john",
age: 30
}
- Object.keys(user) = ["name", "age"]
- Object.values(user) = ["John", 30]
- Object.entries(user) = [ [ "name, "John" ], ["age": 30] ]
아래 예시처럼 Object.values를 사용하면 프로퍼티 값을 대상으로 원하는 작업을 수행할 수 있습니다.
let user = {
name: "Byean",
age: 30
};
// 값을 순회
for (let value of Object.values(user)) {
alert(value); // Byean 과 30이 연속적으로 출력된다.
}
Object.keys, values, entries는 심볼형 프로퍼티를 무시한다.
for..in 반복문처럼, Object.keys, Object.values, Object.entries는 키가 심볼형인 프로퍼티를 무시합니다.
형태로 반환해주는 메서드인 Object.getOwnPropertySymbols를 사용하면 됩니다.
getOwnPropertySymbols 이외에도 키 전체를 배열 형태로 반환해주는 메서드인 Reflect.ownKeys(obj)
를 사용해도 괞찬습니다.
객체 변환하기
객체에는 map,filter와 같은 배열 전용 메서드를 사용할 수 없습니다.
하지만 Object.entries와 Object.fromEntries를 순차적으로 적용하면 객체에서도 배열 전용 메서드를 사용할 수
있습니다. 적용방법은 다음과 같습니다.
- Object.entries(obj)를 사용해 객체의 키-값 쌍이 요소의 배열을 얻습니다.
- 1에서 만든 배열에 map등의 배열 전용 메서드를 적용합니다.
- 2에서 반환한 배열에 Object.fromEntries(array)를 적용해 배열을 다시 객체로 되돌립니다.
이 방법을 사용해서 가격 정보가 저장된 객체 price의 프로퍼티 값을 두배로 늘려보겠습니다.
let prices = {
banana: 1,
orange: 2,
apple: 3
}
let doublePrices = Object.fromEntries(
// 객체를 배열로 변환해 배열 전용 메서드인 map을 적용하고, fromEntries를 사용해 배열을 다시 객체로 되돌림
Object.entries(prices).map(([key,value]) => [key, value * 2])
)
console.log(doublePrices.apple) // 6
객체 합치기
Object.assign()을 이용하면 객체를 합치는 것이 가능합니다. 또한 합칠때 2개의 객체가 같은 프로퍼티를 가지고 있다면
그 값을 덮어쓰게 해주고, 객체의 복제에서도 사용될 수 있습니다.
const target = {a: 1, b: 2}
const source = {c:3, d: 4}
const returnTarget = Object.assign(target, source);
console.log(target);
console.log(source)
console.log(returnTarget);
{ a: 1, b: 2, c: 3, d: 4 }
{ c: 3, d: 4 }
{ a: 1, b: 2, c: 3, d: 4 }
Object.assign의 리턴값에는 target이라는 것이 들어간걸 볼 수 있습니다.
오브젝트 배열 요소 갱신
3개의 객체가 들어있는 객체가 있다고 가정해보면
person = [
{
firstName: "Kim",
lastName: "Mun",
},
{
firstName: "John",
lastName: "So",
},
{
firstName: "Kang",
lastName: "Hee",
},
]
2번째의 배열 객체에는 lastName만을 변경하고 싶다면 Object.assgin을 이용할 수 있습니다.
persons = [
{
firstName: "Kim",
lastName: "Mun",
},
{
firstName: "John",
lastName: "So",
},
{
firstName: "Kang",
lastName: "Hee",
}
];
preson = {
firstName: "Kim",
lastName: "yun"
}
Object.assign(persons[1],preson);
'프론트 엔드 > Javascript' 카테고리의 다른 글
[Javascript] 정규표현식 - 정규표현식이란? RegExp 와 플래그 (0) | 2022.02.07 |
---|---|
[Javascript] 디바운싱과 쓰로틀링 (0) | 2022.02.02 |
[Javascript] Promise.all 이란? (0) | 2022.02.02 |