객체 구조 분해 할당 복습 JS 21.04.15


구조 분해 할당(Destructuring assignment)은 array나 object의 속성을 분해하여 그 value를 개별 변수에 담을 수 있게하는 JS의 표현식.

  • 기본 할당
// syntax

// 객체 선언 후 키&값 할당
let 객체 = { 키1: 값1, 키2, 값2 }

// 구조 분해 할당 후 선언 : 각 키를 변수로 선언 후 값 할당 가능.
let { 키1, 키2 } = 객체
// 키1에 객체의 값1이 할당되고 키2에 객체의 값2가 할당된다.
let creamer = { name: 'terry', job: 'dev' }

console.log(name);
console.log(job);
// name과 job은 변수가 아닌 creamer의 key이므로 어떠한 value도 표시되지 않는다.

let { name, job } = creamer;
// name과 key라는 변수에 creamer 객체가 가진 각 value를 할당한다.

console.log(name);
// terry
console.log(job);
// job
  • 별도의 객체 선언 없이 바로 할당
// syntax
let 변수1, 변수2;

// 괄호()는 선언 없이 바로 할당을 위해 필요한 문법이다.
({변수1, 변수2} = {변수1 : 값1, 변수2: 값2})
// === let {변수1, 변수2} = {변수1 : 값1, 변수2: 값2}
// 괄호 없이 사용하고 싶다면 선언을 해줘야한다.

// 괄호 없이 사용하는 경우
{변수1, 변수2} = {변수1 : 값1, 변수2: 값2}
왼쪽에 있는 {변수1, 변수2} 객체 리터럴이 아닌 블록으로 간주되기 때문이다.
let name, job;

({name, job} = {name : 'terry', job: 'dev'})
  • 새로운 변수 이름으로 할당
// syntax
let 객체 = { 키1: 값1, 키2: 값2 }

let { 키1: 변수1, 키2: 변수2 } = 객체;
// 키1의 변수명을 변수 1로 변경하고 키1의 값 할당
// 키2의 변수명을 변수 2로 변경하고 키2의 값 할당
let creamer = { name: 'terry', job: 'dev' }

let {name: engName, job: secondJob} = creamer;

console.log(name);
console.log(job);
// 변수명을 변경해서 할당 했기 때문에 아무것도 나오지 않는다. 

console.log(engName);
// terry
console.log(secondJob);
// dev
  • 기본 값 할당 : 객체를 해체하여 나온 값이 undefined인 경우, 변수에 기본값을 할당 가능
// syntax
let { 변수명1(키1) = 기본값1, 변수명2(키2) = 기본값2 } = { 키1: 값1 }
//  객체에 키2&값2가 undefined이므로 변수명2(키2)에는 기본값2가 할당된다.
// 객체의 키1은 값1이 undefinde가 아니므로 변수명1(키1)은 객체의 값1 할당
// name에 기본 값으로 creamer 할당, job의 기본값으로 dev 할당
// 객체에는 name의 값만 있으므로 name만 변경되고 job은 기본 값을 할당한다.
let { name = 'creamer', job = 'dev' } = { name: 'terry' }

console.log(name)
// terry
console.log(job);
// dev
  • 기본값을 갖는 새로운 이름의 변수에 할당하기
// syntax
let { 키1(변수명1) : 변경할 변수명1 = 기본값1, 키2(변수명2) : 변경할 변수명2 =  기본값2 }
= { 키1: 값1 }

// 키1(변수명1)을 변경할 변수명1로 변경한 후 값1을 할당한다.

// 키2의 값이 없으므로(undefined) 키2(변수명2)는 변경할 변수명 2로 변경된 후 기본값2를 할당한다.
let { name: engName = 'creamer', job: secondJob = 'dev' } = { name: 'terry' }

console.log(engName)
// terry
console.log(secondJob)
// dev
  • 함수 파라미터로 기본값 설정하기
let helloDev = function({ greeting = 'hello', language: lang = 'JS' } = { } ) {
    console.log(greeting, lang)
}

helloDev()
// hello JS

helloDev( { lang: 'CSS' } )
// hello JS

helloDev( { language: 'CSS' } )
// hello CSS
// lange이 아닌 language로 써줘야한다.
// 인자로 들어가는 객체는 파라미터의 오른쪽 변을 의미하기 때문이다.
// // 함수의 파라미터의 우측변에 빈 객체를 할당하지 않고 함수를 작성 가능 하지만 
// 빈 객체를 없앤다면 함수 호출 시 반드시 인자가 하나 들어가야한다.
let helloDev = function({ greeting = 'hello', language: lang = 'JS' } ) {
    console.log(greeting, lang)
}

helloDev();
// VM491:1 Uncaught TypeError: Cannot read property 'greeting' of undefined

// 위 함수는 무조건 객체를 인자로 사용해야할 경우 유용하다.
  • 중첩된 객체 및 배열의 구조 분해
let metadata = {
    title: "Scratchpad",
    translations: [
       {
        locale: "de",
        localization_tags: [ ],
        last_edit: "2014-04-14T08:43:37",
        url: "/de/docs/Tools/Scratchpad",
        title: "JavaScript-Umgebung"
       }
    ],
    url: "/en-US/docs/Tools/Scratchpad"
};

// title을 engTitle로 변경 한 후 거기에 metadata의 title의 값을 할당
// translations 안에 있는 배열 안에 있는 객체 안에있는 url의 이름을 URL로 변경 한후 해당 값 할당
let { title: engTitle, translations: [ { url: URL } ] } = metadata;

console.log(engTitle)
// "Scratchpad"
console.log(URL)
// /de/docs/Tools/Scratchpad
  • for of 반복문과 구조 분해
// 객체들을 가진 배열 people
let people = [
  {
    name: "Mike Smith",
    family: {
      mother: "Jane Smith",
      father: "Harry Smith",
      sister: "Samantha Smith"
    },
    age: 35
  },
  {
    name: "Tom Jones",
    family: {
      mother: "Norah Jones",
      father: "Richard Jones",
      brother: "Howard Jones"
    },
    age: 25
  }
];

// 배열을 순회하기 위해 for-of 문 사용
// n 변수에 people의 name 할당, f 변수에 people의 family 객체 안에 있는 father의 값 할당
for ( let {name: n, family: { father: f} } of people ) {
    console.log(`Name: ${n}, Father: ${f}`)
}

// Name: Mike Smith, Father: Harry Smith
// Name: Tom Jones, Father: Richard Jones
  • 함수 매개변수로 전달된 객체에서 필드 분해 (user 객체로부터 id, displayName 및 firstName을 분해 후 출력)
function userId( {id} ) {
    return id;
}

function whois( { displayName, fullName: { firstName: name } } ) {
    console.log(displayName + " is " + name);
}

let user = {
  id: 42,
  displayName: "jdoe",
  fullName: {
      firstName: "John",
      lastName: "Doe"
  }
};

// 아래 함수를 실행하면 함수의 인자는 { id } = user
userId(user) // 42

// 아래 함수를 실행하면 함수의 인자는 { displayName, fullName: { firstName: name } = user
whois(user) // jdoe is John
  • 계산된 속성 이름과 구조 분해
let key = "job";
let { [key]: fullTimeJob } = { job: "dev" };
// === let { job: fullTimeJob } = { job: "dev" };

console.log(fullTimeJob); // "dev"
  • 객체 구조 분해에서 Rest
// rest에 나머지 할당. rest = { c: 30, d: 40 }
let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
a; // 10
b; // 20
rest; // { c: 30, d: 40 }
  • 실습 예제 : getChanged 함수 실행시 user 객체의 company.name 변경한 값 출력 (spread syntax 사용). 원본 객체 user는 변경 X.
let user = {
    name: 'terry',
    company: {
        name: 'unemployed',
        skill: ['Development', 'Writing'],
        role: {
            name: 'Blockchain Engineer'
        }
    },
    age: 30
}

let companyTurover = (companyName) => {
    return {
        // 객체 user를 spread syntax를 사용해 풀어서 복사해준다.
        ...user,
        // 객체 user의 모든 내용이 들어간 상태.

        // company의 값 변경
        company: {
            // company에 ...user.company의 모든 값을 풀어준다.
            ...user.company,
            // name을 변수로 받은 companyName으로 바꿔준다.
            name : companyName
        }
    }
}

let changeRole = (role) => {
    return {
        ...user,
        company : {
            ...user.company,
            role: { name: role }
        }
    }
}

companyTurover('google')
// {
//  name: 'terry',
//  company: {
//      name: 'google',
//      skill: ['Development', 'Writing'],
//      role: {
//          name: 'Blockchain Engineer'
//      }
//  },
//  age: 30
// }

changeRole('CTO')
// {
//  name: 'terry',
//  company: {
//      name: 'google',
//      skill: ['Development', 'Writing'],
//      role: {
//          name: 'CTO'
//      }
//  },
//  age: 30
// }





© 2020.11. by creamer

Powered by CREAMer