
한줄 요약: 객체로 선언해서 export했으면, import 할 때도 객체로 불러와야 함.
레이어드 패턴에서 함수선언이 제대로 되지 않았음. → 멘토에게 질문했으나, 곧바로 "구조분해할당 공부 안했죠?" 피드백 들음.
// 잘못쓴것
// dataSource.js
const { DataSource } = require("typeorm");
const appDataSource = new DataSource({
type: process.env.DB_CONNECTION,
host: process.env.DB_HOST,
port: process.env.DB_PORT,
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
});
module.exports = { appDataSource };
// productDao.js
const appDataSource = require("./dataSource");
const lookupAllProducts = async () => {
try {
return await appDataSource.query(
`SELECT
id,
name,
price,
category_id,
description,
thumbnail_image,
hover_image,
detail_information
From products`
);
} catch {
const error = new Error("dataSource Error");
error.statusCode = 400;
throw error;
}
};
// 중략
// appDataSource.query가 function이 아니라는 에러 출력
뭐가 잘못되었는지 아시겠나요?
구조 분해 할당 구문은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식입니다.
사실 위 링크가 이 포스팅보다 더 값지고 유익하다.
배열 또는 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 자바스크립트 표현식이라고 한다. 함수에 객체나 배열을 전달해야 하는 경우, 또는 객체나 배열에 저장된 데이터 전체가 아닌 일부만 필요한 경우 해당 객체나 배열을 변수로 분해할 수 있게 해주는 것이 구조분해할당.
const arr = [1, 2, 3];
const [a, b, c] = arr;
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
→ 2째 줄에서 배열 arr의 요소들을 각각 변수 a, b, c에 할당시켜줌. 그러니까 두번째 줄은 아래와 같은 선언이 압축되어 있는 것임.
const a = arr[0];
const b = arr[1];
const c = arr[2];
const obj = { name: 'xxx', age: 100 };
const { name, age } = obj;
console.log(name); // 'xxx'
console.log(age); // 100
→ 2째 줄에서 각각의 키들과 그 값들을 name과 age라는 변수로 선언.
그러니까 두번째 줄은 아래와 같은 선언이 압축되어 있는 것임.
const name = obj.name;
const age = obj.age;
- 주의사항: 객체 구조분해할당 시 중요한 것은 변수로 지정해 주는 값이 키값과 같아야 한다. 별도로 키값을 따로 설정해주려면 아래와 같은 절차가 필요하다. 키값을 찾을 수 없으면 undefined가 된다.
const obj = { name: 'xxx', age: 100 };
const { name: notName, age: notAge } = obj;
console.log(notName); // 'xxx'
console.log(notAge); // 100
배열 객체의 중첩된 요소에서도 적용 가능하며, 필요한 속성만 선택해 할당할 수도 있다.
const data = {
name: 'John Doe',
age: 30,
address: {
city: 'New York',
country: 'USA'
},
hobbies: ['reading', 'traveling', 'cooking']
};
// 객체의 중첩된 요소 구조 분해 할당
const { name, age, address: { city, country }, hobbies: [hobby1, hobby2, hobby3] } = data;
console.log(name); // 'John Doe'
console.log(age); // 30
console.log(city); // 'New York'
console.log(country); // 'USA'
console.log(hobby1); // 'reading'
console.log(hobby2); // 'traveling'
console.log(hobby3); // 'cooking'
→ 만약 구조분해할당 없이 각 변수들을 지정해줘야 했다면 아래와 같았을 것이다.
const name = data.name;
const age = data.age;
const city = data.address.city;
const country = data.address.country;
const hobby1 = data.hobbies[0];
const hobby2 = data.hobbies[1];
const hobby3 = data.hobbies[2];
//어후 끔찍해;;
1. 코드 가독성, 간결성(유지보수성): 변수할당하는 프로세스가 한줄로 간단히 끝난다.
2. 변수 이름 통일성: 변수 이름을 원하는 대로 지정할 수 있다.
3. 중첩된 구조 처리: 중첩된 객체나 배열의 요소를 간단하게 추출 가능하다. 복잡한 데이터 구조를 다룰 때 유용하다.
일단 지금 당장 생각나는 활용처는 다음과 같다.
1. 다른 곳에서 객체형태로 정의한 함수를 소환할 때, 객체로 소환해야함.
2. 특히 typeorm을 사용하여 dao레벨에서 데이터를 추출해 낸 경우, 추출해 낸 데이터 그 자체는 배열로 감싸여 나오기 때문에, 쿼리문을 선언할 때 배열로 감싸 선언해 주면 리턴값으로 배열은 벗겨낸 데이터로 정제해 낼 수 있다. 그렇게 한다면 dao에서 추출한 데이터를 서비스 레벨로 넘겨 활용할 때, 해당 데이터가 배열이 아닌 전제 하에 비즈니스 로직을 작성할 수 있게 된다.