구조분해할당-객체

오늘도 삽질중·2022년 10월 13일
0

Javascript

목록 보기
1/5

함수에 객체나 배열을 전달할때 전체가 아닌 일부만 필요한 경우가 있다. 이럴때 객체나 배열을 변수로 ‘분해’할 수 있게 해주는 문법이 구조 분해할당을 사용한다.

📓 객체

✅ 우측에는 분해하고자 하는 객체, 좌측엔 상응하는 객체 프로퍼티 '패턴'을 넣는다.

let triangle = {
   		title: "smallTriangle",
     	width: 100
     	height: 200
   }
   
	let {title, width, height} = triangle
	alert(title);  // smallTriangle
	alert(width);  // 100
	alert(height); // 200

✅ 분해하려는 객체의 프로퍼티와 변수의 연결을 원하는 대로 조정할 수도 있다. 객체 프로퍼티를 프로퍼티 키와 다른 이름을 가진 변수에 저장해본다. triangle.width를 w라는 변수에 저장해보자.

	let triangle = {
    	title: "smallTriangle",
      	width: 100
      	height: 200
    }
    
    const {title, width: w, height: h} = triangle
    // width -> w
	// height -> h
	// title -> title
    
    alert(title);  // smallTriangle
	alert(w);      // 100   
	alert(width)   // ReferenceError: width is not defined
	alert(h);      // 200
	
  • 내가 구조분해 포스팅을 하게된 이유

    위의 캡쳐본과 같이 두 개의 데이터를 페칭해올 때 isLoading이라는 값이(boolean) 두 개 쓰였는데 객체의 프로퍼티를 프로퍼티 키와 다른 이름을 가진 변수에 저장하는 방법을 사용한것을 볼 수 있다.

✅ 프로퍼티가 없는 경우를 대비해서 = 를 사용해 기본값을 설정하는 것도 가능하다.

let options = {
	title: "triangle"
}
let {width=100, height=200, title} = options
alert(title);  // Menu
alert(width);  // 100
alert(height); // 200

배열 혹은 함수의 매개변수에서 했던 것처럼 객체에도 표현식이나 함수 호출을 기본값으로 할당할 수 있다.
물론 표현식이나 함수는 값이 제공되지 않았을 때 평가 혹은 실행 된다. 아래 예시를 실행하면 width 값만 물어보고 title값은 물어보지 않고 있다.

let options = {
  title: "Menu"
};

let {width = "width?", title = "title?"} = options;

width  //'width?'
title  //'Menu' 👉 구조분해에서 할당한 값보다 객체의 프로퍼티 값이 더 우선순위인것을 알 수 있다. 

콜론, 할당 연산자도 동시에 사용가능하다.

let options = {
  title: "Menu"
};

let {width:w = "width?", title:t = "title?"} = options;

w // 'width?'
t // 'Menu'

✅ ...rest패턴

나머지 패턴(rest pattern)을 사용하면 배열에서 했던것처럼 나머지 프로퍼티를 어딘가에 할당하는것이 가능하다.
(cf 모던 브라우저는 나머지 패턴 지원, 구식브라우저는 지원 안함. 물론 바벨 이용하면 가능)

let triangle = {
    	  title: "smallTriangle",
      	width: 100,
      	height: 200
    }

let {title, ...rest} = triangle
rest.width // 100
rest.height // 200
title // 'smallTriangle'
    

✅ let 없이 사용하기

보통 let {...} = {...} 또는 const {...} = {...}이런 형식으로 구조분해를 했는데 다른 방법이 있다.
아래를 보자.

  • let 없이 구조분해를 할 경우..에러뜸
  • ()로 감싸준다. 사용 가능!

✅ 중첩 구조 분해

객체나 배열이 다른 객체나 배열을 포함하는 경우, 좀 더 복잡한 패턴을 사용하면 중첩 배열이나 객체의 정보를 추출할 수 있다. 이를 중첩 구조 분해(nested destructuring)이라고 한다.

let options = {
  size: {
    width: 100,
    height: 200
  },
  items: ["spongeBob", "zingzingE"],
  extra: true
};

let {size : {width, height}, items:[item1, item2], extra, title="animation" } = options

width // 100
height // 200
item1 // 'spongeBob'
item2 // 'zingzingE'
extra // true
title // 'animation'

🚀 주의!

  • 위의 예시에서 size와 items 전용 변수는 없다는 점에 유의하자. 전용 변수 대신 우리는 size와 items안의 정보를 변수에 할당하였다. 아래 캡쳐본과 같이 에러 뜬다.

  • 공부하다가.. 이것도 중첩 구조 분해의 일종인듯 하다. (아래 캡쳐본은 콘솔)

  const changeTodo = (e: React.FormEvent<HTMLInputElement>) => {
    console.log(e.currentTarget);
    const {
      currentTarget: { value },
    } = e;

✅ 함수 매개 변수 문법

  • 함수에 매개변수가 많은데 선택적으로 몇개만 쓰이는 경우가 종종 있다.
function triangle(title = "Untitled", width = 200, height = 100, items = []) {
  // ...
}

이렇게 함수를 작성하면 넘겨주는 인수의 순서를 잘 고려해서 넘겨주어야 한다.
아래의 코드를 보자.

// 기본값을 사용해도 괜찮은 경우 아래와 같이 undefined를 여러 개 넘겨줘야 합니다.
triangle("smallTriangle", undefined, undefined, ["Item1", "Item2"])

가독성이 떨어짐을 느낄 수 있다. 꽤나 더러움.. => 이럴때 구조분해를 통해 깔끔하게 만들어보자.


// 함수에 전달할 객체
let options = {
  title: "smallTriangle",
  items: ["Item1", "Item2"]
};

// 똑똑한 함수는 전달받은 객체를 분해해 변수에 즉시 할당함
function triangle({title = "Untitled", width = 200, height = 100, items = []}) {
  // title, items – 객체 options에서 가져옴
  // width, height – 기본값
  alert( `${title} ${width} ${height}` ); // smallTriangle 200 100
  alert( items ); // Item1, Item2
}
triangle(options)

중첩 객체와 콜론을 섞어 좀 더 복잡한 구조 분해도 가능하다.

let options = {
  title: "smallTriangle",
  items: ["Item1", "Item2"]
};

// 똑똑한 함수는 전달받은 객체를 분해해 변수에 즉시 할당함
function triangle({title = "Untitled", width:w = 200, height:h = 100, items = []}) {

  alert( `${title} ${w} ${h}` ); // smallTriangle 200 100
  alert( item1 ); // Item1
}
triangle(options)
  • 결국 함수 매개변수 문법은 구조 분해 할당 문법과 동일하다.
function({
  incomingProperty: varName = defaultValue
  ...
})

incomingProperty는 varName에 할당된다. 만약 값이 없다면 defaultValue가 기본값으로 사용될 것이다.
참고로 이렇게 함수 매개변수를 구조 분해할 땐, 반드시 인수가 전달된다고 가정된고 사용한다는 점에 유의해야한다. 모든 인수에 기본값을 할당해 주려면 빈 객체를 명시적으로 전달해야한다.

showMenu({}); // 모든 인수에 기본값이 할당됩니다.

showMenu(); // 에러가 발생할 수 있습니다.

이 문제를 예방하려면 빈 객체 {}를 인수 전체의 기본값으로 만들면 된다.

function showMenu({ title = "Menu", width = 100, height = 200 } = {}) {
  alert( `${title} ${width} ${height}` );
}

showMenu(); // Menu 100 200

이처럼 인수 객체의 기본값을 빈 객체 {}로 설정하면 어떤 경우든 분해할 것이 생겨서 함수에 인수를 하나도 전달하지 않아도 에러가 발생하지 않는다.

출처 및 참고 문헌
https://ko.javascript.info/destructuring-assignment

profile
의미없는 삽질은 없다1

0개의 댓글