이전에 배열을 공부하면서 구조 분해 할당을 배웠는데 실제로 적용해 보는 거랑은 또 다른 것 같다. 코드 구조를 보다가 가독성을 높일 수 있게 바꿀 수 있는 방법으로 쓸 수 있을 것 같아 리팩토링 해보았다.
먼저 구조 분해 할당에 대해 알아보고, 어떻게 적용했는지 말하겠다!
구조 분해 할당 Destructuring assignment
구조 분해 할당 구문은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식이다.
이를 통해 데이터 뭉치(그룹화)를 쉽게 만들 수 있다!
변수에 나머지 할당하기
구조 분해 할당의 구문은 할당문의 좌변 => 원래 변수로 어떤 값을 분해하여 할당할지 정의한다.
const people = ["😎", "😡", "🥸", "🥶", "😳"];
const [first, second, ...others] = people;
console.log(first); // 😎
console.log(second); // 😡
console.log(others); // [ '🥸', '🥶', '😳' ]
구조 분해 할당은 Perl이나 Python 등 다른 언어가 갖고 있는 기능!
기본값
분해한 값이 undefined일 때를 대비하여 기본값을 설정해둘수도 있다.
const point = [1, 2];
const [x, y, z = 0] = point;
console.log(x); // 1
console.log(y); // 2
console.log(z); // 0
함수가 반환한 배열 분석
함수는 이전부터 배열을 반환할 수 있었다. 구조 분해를 사용하면 반환된 배열에 대한 작업을 더 간결하게 수행할 수 있다.
function createEmoji() {
return ["thirsty", "🥵"];
}
const [title, emoji] = createEmoji();
console.log(title); // thirsty
console.log(emoji); // 🥵
객체 구조 분해
const nami = { name: "Nami", age: 100, job: "s/w engineer" };
function display({ name, age, job }) {
console.log("이름", name); // 이름 Nami
console.log("나이", age); // 나이 100
console.log("직업", job); // 직업 s/w engineer
}
display(nami);
객체 내부 구조에 새로운 값을 추가하는 방법도 있다.
const { name, age, job: occupation, pet = "강아지" } = nami;
console.log(name); // Nami
console.log(age); // 100
console.log(occupation); // s/w engineer
console.log(pet); // 강아지
객체 중첩 구조에서 속성의 값을 바꾸려면..?!
const property = {
nickName: "dot pattern shoes",
styles: {
size: 225,
color: "red",
},
};
function changeColor({ styles: { color } }, colorChange) {
color = colorChange;
console.log(color); // skyblue
}
changeColor(property, "skyblue");
Refactoring 해보기
리팩토링 해볼 코드는 날씨 API를 적용하고 경도 위도를 기반으로 해당 위치와 실시간 날씨 이미지와 온도를 알려주는 영역이다.
우선 이건 강의를 베이스로 작성한 코드였는데, 그 코드에 날씨 코드를 인식하여 img를 불러오는 기능을 추가했던 터라 더욱 지저분해 보인다.
Before
const API_KEY = "****";
function onGeoOK(position) {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
const url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric`;
fetch(url)
.then((response) => response.json())
.then((data) => {
const weather = document.querySelector("#weather");
const weatherImg = document.createElement("img");
weatherImg.src = `../img/icons/${data.weather[0].icon}.png`;
weather.prepend(weatherImg);
const weatherTxt = weatherImg.nextElementSibling;
weatherTxt.innerText = `${data.weather[0].description} · ${Math.round(
data.main.temp
)}°C `;
const city = weather.querySelector("span:last-child");
city.innerText = `· 📍 ${data.name}`;
});
}
function onGeoError() {
alert("Can't find you");
}
After
const API_KEY = "****";
const weather = document.querySelector("#weather");
function displayWeather(data) {
const { name } = data;
const { description, icon } = data.weather[0];
const { temp } = data.main;
const weatherImg = document.createElement("img");
weatherImg.src = `../img/icons/${icon}.png`;
const weatherTxt = document.createElement("span");
weatherTxt.innerText = `${description} · ${Math.round(temp)}°C `;
const city = document.createElement("span");
city.innerText = `· 📍 ${name}`;
weather.appendChild(weatherImg);
weather.appendChild(weatherTxt);
weather.appendChild(city);
}
function onGeoOK(position) {
const { latitude: lat, longitude: lon } = position.coords;
const url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric`;
fetch(url)
.then((response) => response.json())
.then(displayWeather)
.catch(onGeoError);
}
function onGeoError() {
alert("Sorry, we couldn't find your location.");
}
navigator.geolocation.getCurrentPosition(onGeoOK, onGeoError);
다른 부분도 변경해서 어떻게 변경되었는지 확인하기 어려우니 똑 떼어서 비교해 보겠다!
// Before
const lat = position.coords.latitude;
const lon = position.coords.longitude;
// After
const { latitude: lat, longitude: lon } = position.coords;
반복되는 부분을 한 줄로 합칠 수 있어서 훨씬 가독성이 좋아졌다.
// Before
const weather = document.querySelector("#weather");
const weatherImg = document.createElement("img");
weatherImg.src = `../img/icons/${data.weather[0].icon}.png`;
weather.prepend(weatherImg);
const weatherTxt = weatherImg.nextElementSibling;
weatherTxt.innerText = `${data.weather[0].description} · ${Math.round(data.main.temp)}°C `;
const city = weather.querySelector("span:last-child");
city.innerText = `· 📍 ${data.name}`;
// After
const { name } = data;
const { description, icon } = data.weather[0];
const { temp } = data.main;
const weatherImg = document.createElement("img");
weatherImg.src = `../img/icons/${icon}.png`;
const weatherTxt = document.createElement("span");
weatherTxt.innerText = `${description} · ${Math.round(temp)}°C `;
const city = document.createElement("span");
city.innerText = `· 📍 ${name}`;
구조도 바꿔서 다른 것도 많이 바뀌었지만 구조 분해 할당에 초점을 맞추어보겠다.
경로 설정을 보기 힘들었던 반면에 상단에 변수에 반복되는 속성값을 할당해 주어서 훨씬 보기 편하게 리팩토링할 수 있었다.
복습 겸 정리했는데 코드는 역시 직접 적용해 보아야 연결이 된다. 더욱 연습하겠다.
[드림 코딩 아카데미 - 자바스크립트 마스터리 (ES6+)]
ChatGPT 🤖
'JavaScript' 카테고리의 다른 글
JavsScript 리소스 우선 순위, fetchpriority, preload, prefetch, preconnect 깊게 알아보자! (0) | 2023.09.03 |
---|---|
비동기? Promise, async/await, fetch API, 골고루 알아보자 (2) | 2023.08.31 |
`innerText`와 `innerHTML`의 차이점을 알아보자! (0) | 2023.08.29 |
내장객체 Math로 랜덤 Background Image 적용하기 (2) | 2023.08.29 |
Date() 생성자와 내장 메서드로 시계 깔끔하게 적용하기 (0) | 2023.08.29 |