본문 바로가기
책을 읽어봅시다/무던한 개발자를 위한 모던한 자바스크립트

[무던한 개발자를 위한 모던한 자바스크립트]값과 변수 (2)

by upswp 2022. 2. 14.
안녕하세요 Samuel 입니다 : )

해당 책의 내용중 저에게 필요한 일부를 메모하는 방식으로 작성하였으며( +@ 느낀점도 살짝살짝 적어봤어요! ), 추가적으로 구글링과 공식문서를 참고해서 글을 작성해봤습니다.

한빛미디어 <나는 리뷰어다> 활동을 위해서 책을 제공받아 작성된 서평입니다.


값과 변수(2)

배열

자바스크립트의 배열은 ‘0’ , ’1’ 처럼 프로퍼티 이름이 문자열인 객체다. (숫자는 프로퍼티 이름으로 사용할 수 없으므로 문자열을 사용한다.)

const numbers = [1,2,3,'many']

JSON (JavaScript Object Notation)

JSON은 애플리케이션 간에 객체 데이터를 주고받는 경량 텍스트 포맷이다. JSON은 객체, 배열 리터럴을 자바스크립트 문법으로 표현하는데, 다음과 같은 제약이 따른다.

  • 객체 리터럴, 배열 리터럴, 문자열, 소수점 숫자, true, false, null 을 값으로 사용한다.
  • 모든 문자열은 작은 따옴표가 아닌 큰따옴표로 구분한다.
  • 모든 프로퍼티 이름은 큰 따옴표로 구분한다.
  • 맨 끝에서 쉼표를 붙일 수 없으며 요소를 생략할 수 없다.

JSON 표기법에 대한 공식 설명은 아래의 링크를 참고하기를 바란다.

http://www.json.org

{ "name" : "Samuel Park", "age" : 30 , "lucky number" : [7, 27], "lucky" : true }
💡 JSON.stringify 메서드는 값이 undefined인 객체 프로퍼티를 생략하며 undefined 값을 갖는 배열은 null로 변환한다.
예를들어
JSON.stringify({ name: [’Samuel’, undefined, ‘Smith’ ], age : undefined }) 의 결과는
문자열 ‘{ “name”:[”Sameul”,null,”Smith”]}’ 다.

 

로깅을 하는 방법으로도 JSON을 사용할 수 있다.

console.log('samuel=${samuel}')

위의 로깅 명령 결과는 다음과 같다.

samuel=[object Object]

다음처럼 log 메서드에 JSON.stringify를 사용해 문제를 해결한다.

console.log(`samuel=${JSON.stringify(samuel)}`)

이 문제는 객체를 포함하는 문자열에서만 발생한다. 즉, 객체를 직접 log 메서드로 출력하면 아무 문제가 없다.

이름과 값을 따로 로깅하는 것도 한가지 방법이다.

console.log('samuel=', samuel, 'jay=', jay)

또는 이를 객체로 만드는 방법도 있다.

console.log({samuel,jay})

// {samuel : {...}, jay : {...}} 객체 로깅

비구조화(destructuring)

비구조화를 이용하면 배열이나 객체의 값을 편리하게 가져올 수 있다.

두 요소를 포함하는 pair 배열이 있다고 가정한다. 다음처럼 요소에 접근할 수 있다.

let first = pair[0]
let second = pair[1]

비 구조화를 이용하면 다음과 같이 표현할 수 있다.

let [first, second] = pair

위 코드는 first, second 변수를 선언하면서 동시에 이들을 pair[0], pair[1]으로 초기화 한다. 왼쪽의 비구조화 할당은 사실 배열 리터럴이 아니다. first, second는 아직 존재하지 않는다. 왼쪽 표현식은 오른쪽 표현식과 어떻게 변수를 일치해야 하는지 설명한다. 조금 더 복잡한 예제를 살펴보면서 변수와 배열 요소를 어떻게 매치하는지 확인해보자.

//first를 1로, second를 2로, third를 3으로 설정
let[first, [second, third]] = [1,[2,3]]

오른쪽의 배열은 외쪽의 패턴보다 많은 요소를 가질 수 있다. 이때 매치되지 않는 요소는 단순히 무시된다.

let[first, second] = [1,2,3]

하지만 배열의 요소가 왼쪽 패턴보다 작다면 매치되지 않는 변수는 undefined를 갖는다.

// first를 1로, second를 undefined로 설정
let[first, second] = [1]

first와 second가 이미 선언되어 있다면 비구조화를 통해서 새 값을 할당할 수 있다.

[first, second] = [4,5]

<aside> 💡 다음은 x,y 변수값을 바꾸는 간단한 코드다.

[ x, y ] = [ y, x ]

</aside>

할당문에 비구조화를 사용할때는 왼쪽 구문에 꼭 변수를 사용하지 않아도 되며 모든 lvalue(할당문의 왼쪽에 나타날 수 있는 모든 표현식을 가리킴)를 사용할 수 있다.

// number[0] = 13, samuel.age = 30와 같은 의미
[numbers[0], samuel.age] = [13,30] 

객체 비구조화도 비슷하다. 객체 비구조화에서는 배열 위치 대신 프로퍼티 이름을 사용한다.

let samuel = {name : 'Samuel', age : 30}
let { name : samuelName, age: samuelAge } = samuel

위 코드는 samuelName과 samuelAge 두 가지 변수를 선언하면서 이들을 오른쪽 객체의 name, age 프로퍼티 값으로 설정한다.

왼쪽 표현식은 객체 리터럴이 아니라는 사실을 기억하자. 왼쪽 표현식은 변수가 어떻게 오른쪽 표현식과 매치하는지를 보여주는 패턴이다.

프로퍼티 이름이 변수와 같을때 객체를 사용해 비구조화 하는것이 가장 효과적이다. 이때 프로퍼티 이름과 콜론을 생략할 수 있다. 다음 코드는 name, age 두변수를 선언하고, 오른쪽 표현식 객체와 동일한 이름의 프로퍼티 값으로 설정한다.

let {name, age} = samuel

위 코드는 다음 코드와 같다.

let { name : name, age: age } = sameul

물론 다음 코드를 길게 표현도 가능하다.

let name = samuel.name
let age = samuel.age
💡 기존 변수를 객체 비구조화로 설정할때는 할당 표현식을 반드시 소괄호로 감싸야 한다. 그렇지 않으면 여는 중괄호를 블록문의 시작으로 해석하기 때문이다.
({name, age} = samuel)

고급 비구조화

객체 비구조화

중첩된 객체를 다음과 같이 비구조화 할 수 있다.

let pat = { name : 'Pat', dob: {day: 14, month: 3, year: 2000}}
let { dob : {year: patsDobYear}} = pat

// patsDobYear 변수를 선언하고 2000으로 초기화

다시한번 강조하지만 두번째 구문의 왼쪽 표현식은 객체가 아니다. 왼쪽 표현식은 변수가 오른쪽 표현식의 값과 어떻게 매치하는지 보여주는 패턴이다.

위의 코드의 의미는 다음과 같다.

let patDobYear = pat.dob.year

객체 리터럴 처럼 계산결과를 프로퍼티 이름으로 사용할 수 있다.

let field = 'Age'
let {[field.toLowerCase()]: samuelAge} = samuel
// samuel[field.toLowerCase()]로 값을 설정

나머지 선언

배열을 비구조화할때 다음 코드처럼 변수이름앞에 ...를 붙여서 나머지 요소를 배열로 담을 수 있다.

numbers = [1,7,2,9]
let[first, second, ...others] = numbers
//firstsms 1, second는 7, others는 [2,9]

오른쪽 표현식의 배열에 충분한 요소가 없으면 나머지 변수는 빈 배열이 된다.

let[first, second, ...others] = [42]
// first는 42 , second는 undefined, others는 []

객체에도 나머지 선언을 적용할 수 있다.

let {name, ...allButName} = samuel
// allButName은 {age : 30}

name을 제외한 모든 다른 프로퍼티를 allButname 변수에 할당한다.

기본값

객체나 배열에서 값을 제공하지 않거나 값이 undefined일때 변수에 할당할 기본값을 제공할 수 있다. 다음 코드처럼 변수 이름 뒤에 등호(=)와 표현식을 추가한다.

let[first, second = 0] = [42]
// first는 42, second는 매치할 요소가 없으므로 0으로 설정
let {nickname = 'None'} = samuel
// samuel에 nickname 프로퍼티가 없으므로 nickname을 'None'으로 설정

기본값 표현식에 기존 변수를 사용할 수 있다.

let {name, nickname = name } = samuel
// name, nickname을 samuel.name으로 설정

 

참고문서

무던한 개발자를 위한 모던한 자바스크립트