객체와 관련된 데이터를 다룰 때 유용하게 쓰는 메서드.
이 메서드들은 객체의 데이터를 배열 형태로 반환하여,
객체의 데이터를 순회하거나 다루기 쉽게 해줌.
const person = { name: "홍길동", age: 25, city: "서울" };
console.log(Object.keys(person)); // ["name", "age", "city"]
console.log(Object.values(person)); // ["홍길동", 25, "서울"]
console.log(Object.entries(person)); // [["name", "홍길동"], ["age", 25], ["city", "서울"]]
자바스크립트에서는 다양한 자료 구조를 다루며, 이들을 순회하기 위해 특정 메서드들이 제공됨. Object.keys, Object.values, Object.entries는 일반 객체에 적용되는 메서드들로,
객체의 키, 값, 키-값 쌍을 배열로 반환.
이와 비교해, Map, Set, Array와 같은 내장 자료 구조에는 자체적인
.keys(), .values(), .entries() 메서드가 존재.
각 전용 메서드와 일반객체 메서드의 차이점은 다음과 같다.
이해안되지만 일단 정의하고 넘어감
호출방식
Map,Set,Array는 .keys(), .values(), .entries()와 같은 인스턴스 메서드를 직접 호출함. 예를 들어, map.keys()는 맵 객체 내의 모든 키를 순회할 수 있는 이터러블 객체를 반환함.
일반 객체는 Object.keys(obj), Object.values(obj), Object.entries(obj)와 같이 Object 전역 객체를 통해 메서드를 호출해야됨. obj.keys() 이런식은 안됨.
사용자가 일반객체에 values()와 같은 메서드를 직접 정의하고 사용할수있기때문에
사용자가 정의한 메서드와 내장 메서드간의 충돌발생가능성도 있음. 그래서
Object.values(obj)와 같은 형태로 호출하면 서로 구분하여 사용할수 있기 때문에 더 유연함.
반환 값의 차이
Map은 키와 값을 연결하는 구조임. 맵에서 제공하는 메서드 (예: .keys(), .values(), .entries())를
사용하면 이터러블 객체를 받게 됨.
'이터러블 객체'란, 반복해서 하나씩 꺼내 볼 수 있는 '목록'과 같은 것. for..of 같은
반복문을 사용하여 이터러블 객체의 내용물을 하나씩 순회 할 수 있음.
일반객체는 진짜 배열을 받게 됨.
그래서 배열의 모든 기능 (.map(), .filter(), .reduce() 등)을 사용할 수 있음.
심볼형 프로퍼티는 객체의 고유한 키로 사용될 수 있는 심볼(symbol) 값을 말함.
Object.keys, Object.values, Object.entries는 심볼형 프로퍼티를 무시하고,
오직 문자열 키에 대해서만 작업함.
심볼형 키를 포함한 객체의 키를 다루고 싶다면,
Object.getOwnPropertySymbols 또는 Reflect.ownKeys(obj) 메서드를 사용해야 함.
객체엔 map, filter 같은 배열 전용 메서드를 사용할 수 없음.
Object.entries와 Object.fromEntries를 순차적으로 적용하면
객체에도 배열 전용 메서드 사용할 수 있음
let prices = {
banana: 1,
orange: 2,
meat: 4,
};
let doublePrices = Object.fromEntries(
Object.entries(prices).map(([key, value]) => [key, value * 2])
);
console.log(doublePrices.meat); // 8
Object.entries(prices)를 사용해 객체의 키-값을 배열로 받음. 여기에 map 배열전용메서드를 사용,
값으로 받은 value를 *2해줌 그리고 다시 Object.fromEntries() 를 사용해 배열을 객채로 돌림.
그런데 나는 공부 하면서 느끼는거지만 (초보자, 입문자 입장)
코드 진행순서가 위에서부터 아래로 자연스럽게 오는게 눈에 잘들어옴.
꼭 비단 이것뿐만이 아니라, 다른 예시에서도
아마 익숙해지게 되면서부터는 간결함을 추구하게 되니깐이러지 않을까? 라는생각은 함.
어쨌든 내기준에서
let prices = {
banana: 1,
orange: 2,
meat: 4,
};
let entries = Object.entries(prices);
let doubledEntries = entries.map(([key, value]) => [key, value * 2]);
let doublePrices = Object.fromEntries(doubledEntries);
console.log(doublePrices.meat); // 8
이런느낌? 위에서부터 차례대로 한줄씩 해주면 눈에는 일단 잘들어와서 좋긴함.
entries로 배열로 바꿔주고 >> 그값을 map으로 변경해주고 >> 그걸 다시 fromEntries로 객채로변환.
물론 이러면 쓰잘대기없는 변수들이 많이 나오긴함. 이것도 권장되는건 아님
아직 잘 모르겠음. 한번에 딱보고 감이 오면 좋은데 머리가 나빠서.
배열이나 객체의 속성을 분해하여 그 값을 개별 변수에 담을 수 있게 하는 JavaScript의 표현식
배열이나 객체로부터 데이터를 쉽게 추출할 수 있음.
어떤 것을 복사한 이후에 변수로 분해(destructurize)해준다.
이 과정에서 분해 대상은 수정 또는 파괴되지 않음
기본문법
let [변수1, 변수2, ...] = 배열;
let arr = ["Bora", "Lee"]
let [firstName, surname] = arr;
console.log(firstName); // Bora
console.log(surname); // Lee
let [a, b, c] = "abc"; // ["a", "b", "c"]
let [one, two, three] = new Set([1, 2, 3]); //이건 아직 모르겠음 Set모름
let user = {};
[user.name, user.surname] = "Bora Lee".split(' ');
console.log(user.name); // Bora
let user = {
name: "John",
age: 30
};
for (let [key, value] of Object.entries(user)) {
//객체를 배열로 바꿈[[name,John],[age,30]] 각각 key, value변수로 들어감
console.log(`${key}:${value}`); // name:John, age:30이 차례대로 출력
}
let user = new Map();
user.set("name", "John");
user.set("age", "30");
for (let [key, value] of user) {
alert(`${key}:${value}`); // name:John, then age:30
}
let guest = "Jane";
let admin = "Pete";
[guest, admin] = [admin, guest];// 이미 저장된 변수값에 값을 새로 넣어줌
console.log(`${guest} ${admin}`); // guest: Pete, admin: Jane
let [firstName,,title] = ["Julius", "Caesar", "Consul"];
//두 번째 요소는 생략되고, 세 번째 요소가 title이라는 변수에 할당됨.
console.log(title); // Consul
let [name1, name2, ...rest] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
console.log(name1); // Julius
console.log(name2); // Caesar
// `rest`는 배열.
console.log(rest[0]); // Consul
console.log(rest[1]); // of the Roman Republic
console.log(rest.length); // 2
let [name = "Guest", surname = "Anonymous"] = ["Julius"];
console.log(name); // Julius (배열에서 받아온 값)
console.log(surname); // Anonymous (기본값)
기본문법
let { 속성1, 속성2, ...} = 객체;
속성1, 속성2는 객체 내의 키 이름과 동일해야 하며, 해당 키에 해당하는 값이 변수에 할당됨.
let options = {
title: "Menu",
width: 100,
height: 200
};
let {height, width, title} = options;
//프로퍼티 순서는 상관없음. {title, width, height},{width, height, title} 똑같음.
console.log(title); // Menu
console.log(width); // 100
console.log(height); // 200
let options = {
title: "Menu",
width: 100,
height: 200
};
let {width: w, height: h, title} = options; // { 객체 프로퍼티: 목표 변수 }
// width -> w
// height -> h
// title -> title
//프로퍼티 width를 변수 w에, 프로퍼티 height를 변수 h에 저장
console.log(title); // Menu
console.log(w); // 100
console.log(h); // 200
let options = {
title: "Menu"
};
let {width = prompt("width?"), title = prompt("title?")} = options;
console.log(title); // Menu
console.log(width); // prompt 창에 입력한 값
let options = {
title: "Menu"
};
let {width: w = 100, height: h = 200, title} = options;
console.log(title); // Menu
console.log(w); // 100
console.log(h); // 200
let options = {
title: "Menu",
height: 200,
width: 100
};
let {title, ...rest} = options;
// title = 이름이 title인 프로퍼티
// rest = 나머지 프로퍼티들
// title엔 "Menu", rest엔 {height: 200, width: 100}이 할당.
console.log(title); // 200
console.log(rest.height); // 200
console.log(rest.width); // 100
let title, width, height;
({title, width, height} = {title: "Menu", width: 200, height: 100});
//구조분해할당을 단독으로 사용할 때는 괄호()로 식을 감싸줘야됨.
//{}가 블록 구문으로 해석될 수 있기 때문에, 괄호로 감싸주어 구조 분해 할당임을 명시
console.log(title); // Menu
console.log(width); // 200
console.log(height); // 100
객체나 배열이 다른 객체나 배열을 포함하는 경우, 복잡한 데이터 구조를 간결하게 분해하여
그 내부의 값을 변수에 쉽게 할당할 수 있게 해주는 문법
let options = {
size: {
width: 100,
height: 200
},
items: ["Cake", "Donut"],
extra: true
};
let {
size: {
width,
height
}, // size는 여기,
items: [item1, item2], // items는 여기에 할당함
title = "Menu" // 분해하려는 객체에 title 프로퍼티가 없으므로 기본값을 사용함
} = options;
console.log(title); // Menu
console.log(width); // 100
console.log(height); // 200
console.log(item1); // Cake
console.log(item2); // Donut
구조 분해 할당을 활용하면 함수의 매개변수를 객체의 형태로 전달하고,
함수 내부에서 필요한 프로퍼티를 쉽게 추출할 수 있음.
이 방법을 사용하면 매개변수의 순서를 신경 쓸 필요가 없고,
선택적 매개변수를 다루기도 용이함
// 함수에 전달할 객체
let options = {
title: "My menu",
items: ["Item1", "Item2"],
width: 300
};
// 똑똑한 함수는 전달받은 객체를 분해해 변수에 즉시 할당함
function showMenu({title = "Untitled", width = 200, height = 100, items = []}) {
// title, items , width – 객체 options에서 가져옴
// height – 기본값
console.log( `${title} ${width} ${height}` ); // My Menu 300 100
console.log( items ); // Item1, Item2
}
showMenu(options);
구조 분해 할당은 중첩된 객체와 배열에도 사용할 수 있으며,
변수 이름을 변경하고 싶을 때 콜론(:)을 활용
let options = {
title: "My menu",
items: ["Item11", "Item22"],
};
function showMenu({
title = "Untitled",
width: w = 100, // width는 w에 할당됨
height: h = 200, // height는 h에 할당됨
items: [item1, item2] // items의 첫 번째 요소는 item1에, 두 번째 요소는 item2에 할당함
}) {
console.log( `${title} ${w} ${h}` ); // My Menu 100 200
console.log( item1 ); // Item11
console.log( item2 ); // Item22
}
showMenu(options);
함수 매개변수를 구조 분해할 때는 인수가 전달되었다고 가정함.
인수를 전혀 전달하지 않는 경우를 처리하기 위해서는
전체 매개변수 객체에 기본값으로 빈 객체 {}를 설정해야 함.
function showMenu({title = "Menu", width = 100, height = 200} = {}) {
console.log( `${title} ${width} ${height}` );
}
showMenu(); // 에러 없이 'Menu 100 200' 출력