[자바스크립트 완벽가이드] 3장_타입, 값, 변수 (3)

유동균·2023년 3월 1일
0
post-thumbnail

9. 타입 변환

자바스크립트는 값의타입을 강제하지 않는다.

자바스크립트가 불 값을 예상하는 곳이라 해도 아무 타입이나 사용 가능하며 자바스크립트가 필요에 맞게 값을 변환한다.
true같은 값은 truthy로, false같은 값은 falsy
자바스크립트가 문자열을 예상한다면, 그 자리에 있는 값은 무엇이든 문자열로 변환된다.
자바스크립트가 숫자를 예상한다면, 그 자리에 있는 값을 숫자로 변환하고 변환이 성공적이지 않다면 NaN을 반환.

10 + " object"	// "10 object";		숫자 10이 문자열로 변환
"7" * "4"		// 28;				두 문자열을 모두 숫자로 변환
let n = 1 - "x"	// n == NaN;		문자열 x는 숫자로 변환 불가
n + " object"	// "NaN object";	NaN은 문자열 "NaN"으로 변환
문자열로숫자로불 값으로
undefined"undefined"NaNfalse
null"null"0false
true"true"1
false"fasle"0
""(빈문자열)0false
"1.2"(숫자)1.2true
"one"(문자열)NaNtrue
0"0"false
-0"0"false
1(0이 아닌 유한한 숫자)"1"true
Infinity"Infinity"true
-Infinity"-Infinity"true
NaN"NaN"false
{}(객체)9.3 참고9.3 참고true
[](빈 배열)""0true
[9](숫자 요소 하나)"9"9true
["a"]join() 메서드 사용NaNtrue
function(){}(임의의 함수)9.3 참고NaNtrue

9.1 변환과 일치

자바스크립트에는 두 값이 같은지 테스트하는 연산자가 두 개 있다.
일치 연산자 ===는 두 피연산자가 다른 타입이면 같지 않다고 판단하며, 동등 연산자 ==를 선택하는 것보다 좋다.

하지만 자바스크립트는 타입 변환이 엄격하지 않으므로 동등 연산자도 정의했다.

null === undefined	// true;	두 값을 같은 것으로 취급한다.
0 == "0"			// true;	비교하기 전에 문자열을 숫자로 변환
0 == false			// true;	비교하기 전에 불 값을 숫자로 변환
"0" == false		// true;	비교하기 전에 두 피연산자를 모두 0으로 변환

값을 다른 타입으로 변환할 수 있다 해도 두 값이 무조건 동등하지는 않다.
예를 들어 불 값을 예상하는 곳에 undefined를 사용하면 이 값은 false로 변환되지만,
undefinedfalse와 동등한 것은 아니다.

9.2 명시적 변환

자바스크립트는 자동으로 타읍을 변환하긴 하지만 때때로 직접 변환해야 할 때도 있다.

명시적으로 타입을 변환하는 가장 단순한 방법은 Boolean(), Number(), String() 함수이다.

Number("3")		// 3;
String(false)	// "false"; false.toString()과 같다.
Boolean([])		// true

null, undefined를 제외한 모든 값에 toString() 메서드가 있으며, 이 메서드의 결과는 보통 String() 함수가 반환하는 값과 같다.

Boolean(), Number(), String() 함수는 모두 new와 함께 호출해서 생성자로 사용할 수 있다.
이런식으로 사용하면 기본 불, 숫자, 문자열 값과 똑같이 동작하는 "래퍼" 객체를 얻는다.
이런 래퍼 객체는 자바스크립트의 초창기에 잠시 사용되었지만, 지금은 사용할 이유가 없다.

묵시적인 타입 변환을 수행하는 자바스크립트 연산자를 타입 변환을 목적으로 쓸 때도 있다.
+ 연산자의 피연산자 중 하나가 문자열이면 다른 피연산자도 문자열로 변환된다.
단항 + 연산자는 피연산자를 숫자로 변환한다.
단항 ! 연산자는 피연산자를 불로 변환한 후 다시 부정한다.

x + ""	// String(x)
+x		// Number(x)
x-0		// Number(x)
!!x		// Boolean(x)

Number 클래스의 toString() 메서드는 선택적으로 기수를 인자로 받는다.
인자를 생략하면 10진수로 변환하고, 2이상 36이하 기수를 넘겨서 그에 맞게 변환한다.

let n = 17;
let binary = "0b" + n.toString(2);	// binary == "0b10001"
let octal = "0o" + n.toString(8);	// octal == "0o21"
let hex = "0x" + n.toString(16);	// hex == "0x11"

숫자를 문자열로 변환해서 소수점 앞뒤에 몇자리를 쓸지, 지수 표기법을 사용할지 등을 결정하고 싶을 때
Number 클래스에 숫자를 문자열로 변환하는 세 가지 메서드가 있다.

  • toFixed()는 숫자를 문자열로 변환할 때 소수점 아래 몇 자리를 표시할지 지정할 수 있다.
    이 메서드는 지수 표기법을 사용하지 않는다.
  • toExponential()은 지수 표기법을 사용해서 숫자를 문자열로 변환한다.
    소수점 앞에는 숫자 하나가 오며, 소수점 아래에는 지정된 자릿수만큼 숫자가 표시된다.
  • toPrecision()은 지정하는 유효 숫자에 따라 숫자를 문자열로 변환한다.
    지정한 유효 숫자가 작아서 숫자의 정수 부분을 정확히 표시할 수 없을 때는 지수 표기법을 사용한다.

위 세가지 메서드는 반올림을 하거나 0을 덧붙인다.

let n = 123456.789;
n.toFixed(0)		// "1234567"
n.toFixed(2)		// "123456.79"
n.toFixed(5)		// "123456.78900"
n.toExponential(1)	// "1.2e+5"
n.toExponential(3)	// "1235e+5"
n.toPrecision(4)	// "1235e+5"
n.toPrecision(7)	// "123456.8"
n.toPrecision(10)	// "123456.7890"

Number() 함수는 문자열을 정수나 부동 소수점 리터럴로 변환 시도한다.
이 함수는 10진 정수에만 동작하며, 리터럴의 일부가 아닌 문자는 모두 무시한다.
전역 함수 parseInt(), parseFloat()는 유연하게 동작한다.
parseInt()는 오직 정수 부분만 유지하지만,
parseFloat()는 정수와 부동 소수점 숫자를 모두 유지한다.

문자열이 0x, 0X로 시작할 경우 parseInt()는 이 문자열을 16진수로 해석한다.

parseInt(), parseFloat()는 모두 시작 부분의 공백은 무시하고 숫자를 최대한 해석한 뒤 숫자가 아닌 문자가 등장하면 그 뒤는 모두 무시한다.
공백이 아닌 첫 번째 문자가 유효한 숫자 리터럴이 아니라면 두 함수 모두 NaN를 반환한다.

parseInt("3 blind mice")	// 3;
parseFloat(" 3.14 meters")	// 3.14;
parseInt("-12.34")			// -12;
parseInt("0xFF")			// 255;
parseInt("0xff")			// 255;
parseInt("-0xff")			// -255;
parseFloat(".1")			// 0.1;
parseInt("0.1")				// 0;
parseInt(".1")				// NaN;		 정수는 .으로 시작할 수 없다.
parseFloat("$72.47")		// NaN;		 숫자는 $으로 시작할 수 없다.

parseInt()는 선택 사항인 두 번째 인자로 기수를 받는다.
기수는 2이상 36이하 범위여야 한다.

parseInt("11",2)	// 3;		(1*2 + 1)
parseInt("ff",16)	// 255;		(15*16 + 15)
parseInt("zz",36)	// 1295;	(35*36 + 35)
parseInt("077",8)	// 63;		(7*8 + 7)
parseInt("077",10)	// 77;		(7*10 + 7)

9.3 객체를 기본 값으로 변환

자바스크립트가 객체를 기본 값으로 변환하는 규칙이 복잡한 이유 중 하나는 일부 객체는 여러 가지 기본 값으로 표현될 수 있다는 점이다.(Date객체는 문자열로도, 숫자인 타임스탬프로도 표현할 수 있다.)

자바스크립트 명세에는 객체를 기본 값으로 변환하는 세 가지 기본적인 알고리즘이 정의되어 있다.

  • 문자열 선호
    이 알고리즘은 기본 값을 반환할 때 문자열로 변환할 수 있다면 문자열 값을 우선한다.
  • 숫자 선호
    이 알고리즘은 기본 값을 반환할 때 숫자로 변환할 수 있다면 숫자 값을 우선한다.
  • 선호 없음
    이 알고리즘은 어떤 기본 타입을 선호하는지 정해 놓지 않았으며 클래스에서 변환 방법을 정의할 수 있다.
    자바스크립트에 내장된 타입중 Date를 제외한 모든 타입이 이 알고리즘에 숫자 선호를 적용한다.
    Date 클래스는 이 알고리즘에 문자열 선호를 적용한다.

객체를 불로 변환
객체는 모두 true로 변환된다.
이 변환에는 알고리즘이 적용되지 않으며, 문자 그대로 모든 객체에 적용된다.
빈 배열, 심지어 래퍼 객체 new Boolean(false) 역시 true이다.

객체를 문자열로 변환
객체를 문자열로 변환해야 할 때 자바스크립트는 먼저 문자열 선호 알고리즘을 사용해 기본 값으로 변환한 다음,
필요하다면 위 9. 타입변환 표의 규칙에 따라 기본 값을 문자열로 변환한다.

문자열 인자를 예상하는 내장 함수에 객체를 전달할 때,
String()을 변환 함수로 호출할 때,
템플릿 리터럴에 객체를 사용할 때 등이 이런 변환에 해당한다.

객체를 숫자로 변환
객체를 숫자로 변환해야 할 때 자바스크립트는 먼저 숫자 선호 알고리즘에 따라 기본 값을 변환한 다음,
필요하다면 위 9. 타입변환 표의 규칙에 따라 기본 값을 숫자로 변환한다.

숫자 인자를 예상하는 자바스크립트의 내장 함수와 메서드가 객체를 받았을 때 이 방법을 사용해 숫자로 변환한다.
또한 숫자 피연산자를 예상하는 연산자 대부분 역시 이 방법을 사용한다.

연산자 변환
+ 연산자는 자바스크립트에서 숫자를 더하고 문자열을 병합한다.
+ 연산자의 피연산자 중 하나가 객체라면 자바스크립트는 해당 피연산자를 선호 없음 알고리즘에 따라 기본 값으로 변환한다.
알고리즘을 적용해서 두 개의 기본 값이 남으면 타입 체크를한다.
피연산자 중 하나라도 문자열이면 다른 하나도 문자열로 변환한 다음 병합한다.
피연산자 모두 문자열이 아니라면 둘 다 숫자로 변환한 다음 더한다.

==, != 연산자는 타입 변환을 허용한다.
피연산자 중 하나가 객체이고 다른 하나가 기본 값이라면 선호 없음 알고리즘을 써서 객체를 기본 값으로 변환한 다음 비교한다.

관계 연산자 <,<=, >, >=는 피연산자의 순서를 비교하며 숫자와 문자열을 비교할 수 있다.
피연산자 중 하나가 객체라면 숫자 선호 알고리즘을 통해 기본 값으로 변환한다.
하지만, 객체를 숫자로 변환하는 경우와는 달리 여기서 숫자 선호 알고리즘이 반환하는 기본 값은 숫자로 변환되지않는다.

Date 객체의 숫자 표현은 <, >로 비교할 수 있는 것이 당연하지만 문자열로 표현은 그렇지 않다.
Date 객체에서 선호 없음 알고리즘은 문자열로 변환하므로,
자바스크립트가 이들 관계 연산자에 대해 숫자 선호 알고리즘을 사용한다는 것은 Date 객체의 순서를 비교할 수 있다는 뜻이다.

toString()valueOf() 메서드
모든 객체는 기본 값으로 변환할 때 사용하는 두 가지 변환 메서드를 상속한다.

첫 번째 메서드인 toString()은 객체의 문자열 표현을 반환한다.

({x : 1, y : 2}).toString()		// "[object Object]"

대부분의 클래스에는 해당 클래스에 더 알맞는 toString() 메서드가 정의되어 있다.

예를 들어,

  • 배열 클래스의 toString() 메서드는 각 요소를 문자열로 변환하고 이들을 콤마로 연결한다.
  • 함수의 toString() 메서드는 사용자 정의 함수에 따라 자바스크립트 소스 코드를 문자열로 변환해서 반환한다.
  • Date 클래스의 toString() 메서드는 사람이 읽기 쉽고 자바스크립트에서 분석할 수 있는 날짜와 시간 문자열을 반환한다.
  • RegExp 클래스의 toString() 메서드는 RegExp 리터럴과 비슷한 문자열을 반환한다.
[1,2,3].toString()						// "1,2,3"
(function(x) { f(x); }).toString()		// "function(x) { f(x); }"
/\d+/g.toString()						// "/\d+/g"
let d = new Date(2023,0,1);				
d.toString()							// "Sun Jan 01 2023 00:00:00 GMT+0900"

두 번째 메서드인 valueOf()는 객체를 표현하는 기본 값이 존재한다면그 값으로 객체를 변환한다.
하지만 객체는 복합된 형태이며 대부분의 객체는 단일한 기본 값으로 펴현하는 것이 불가능하다.
따라서 기본 valueOf() 메서드는 기본 값이 아니라 객체 자체를 반환한다.

  • 문자열, 숫자, 불의 래퍼 클래스의 valueOf() 메서드는 그냥 그 기본 값을 반환한다.
  • 배열, 함수, 정규 표현식은 기본 메서드를 상속한다. 이들 타입의 인스턴스에서 valueOf()를 호출하면 객체 자체를 반환한다.
  • Date 클래스의 valueOf() 메서드는 날짜를 내부적으로 저장하는 형식인 1970년 1월 1일로부터 경과된 밀리초를 반환한다.
    		let d = new Date(2023,0,1);		// 2023년 1월 1일
    		d.valueOf()						// 1672498800000

객체에서 기본 값으로 변환하는 알고리즘

  • 문자열 선호 알고리즘
    먼저 toString() 메서드를 시도한다.
    이 메서드가 정의되어있고 기본 값을 반환한다면 자바스크립트는 그 값을 사용한다.
    설령 그 기본 값이 문자열이 아니더라도 그대로 사용한다.
    toString()이 존재하지 않거나 객체를 반환한다면 자바스크립트는 valueOf()를 시도한다.
    이 메서드가 존재하고 기본 값을 반환한다면 자바스크립트는 그 값을 사용한다. 그렇지 않으면 TypeError가 일어남.

  • 숫자 선호 알고리즘
    문자열 선호 알고리즘과 비슷하지만, valueOf()를 먼저 시도하고 toString()을 두 번째로 시도한다.

  • 선호 없음 알고리즘
    변환하는 객체의 클래스에 따라 다르게 동작한다.
    객체가 Date 객체일 경우 문자열 선호 알고리즘을 사용한다.
    그 외의 객체에서는 숫자 선호 알고리즘을 사용한다.

10. 변수 선언과 할당

이름 또는 식별자를 사용해 값을 표현하는 것은 컴퓨터 프로그래밍의 가장 기본적인 기술 중 하나이다.
값에 이름을 부여하면 프로그램에서 그 값을 참조하고 사용할 수 있다.
이런 과정을 일반적으로 변수에 값을 할당한다고 말한다.

변수라는 용어는 새로운 값을 할당할 수 있음을 암시한다.
즉, 프로그램이 실행됨에 따라 변수에 연결된 값이 바뀔 수 있다.

값에 이름을 영구히 할당할 때는 변수 대신 상수라고 부른다.

자바스크립트 프로그램에서 변수나 상수를 쓰기 전에 반드시 선언을 먼저 해야한다.
ES6 이후에는 let, const 키워드를 사용해 변수를 선언한다.

10.1 let과 const를 사용한 선언

최신 자바스크립트(ES6 이후)에서는 let 키워드를 사용해 변수를 선언한다.

let i;
let sum;

// let 문 하나에 변수 여럿을 선언할 수도 있다.
let i, sum;

가능하면 아래와 같이 변수를 선언할 때 초기값을 할당하는 것이 좋은 프로그래밍 습관이다.

let message = "hello";
let i = 0; j = 0; k = 0;
let x = 2, y = x * x;		// 직전에 선언한 변수를 이용해 초기화할 수도 있다.

let 문에서 변수에 초기값을 할당하지 않으면 값을 할당할 때까지 undefined로 남는다.

상수를 선언할 때는 const를 사용한다.
constlet과 비슷하지만, 선언할 때 반드시 값을 할당해 초기화해야 한다.
상수의 값은 변경할 수 없다. 상수의 값을 바꾸려고 하면 TypeError가 일어난다.

반드시 지켜야 하는 것은 아니지만, 상수를 선언할 때는 대문자를 사용해 변수와 구별하는 관습이 있다.

변수와 상수 스코프
변수의 스코프(scope)는 프로그램 소스 코드에서 해당 변수가 정의된 영역이다.
letconst로 선언한 변수와 상수는 블록 스코프를 가진다.
이 말은 letconst문이 존재하는 블록 안에서만 해당 변수와 상수가 유효하다는 뜻이다.

자바스크립트의 클래스와 함수 정의는 블록이고, if/else문,while 루프,for 루프 등의 바디 역시 블록이다.

선언이 어떤 코드 블록에도 속하지 않고 최상위 레벨에 있을 경우 이를 전역 변수/상수라고 부르며, 이들은 전역 스코프를 가진다.

반복 선언
같은 스코프에서 같은 이름으로 let이나 const 선언을 하나 이상 사용하는 것은 문법 에러이다.

하지만, 중첩된 스코프에서 같은 이름의 변수를 선언하는 것은 가능하다.

const x = 1;			// x를 전역 상수로 선언
if (x === 1) {
	let x = 2;			// 블록 안에서 다시 선언
  	console.log(x);		// 2;
}
console.log(x);			// 1; 전역 스코프
let x = 3;				// x를 재선언 하는 것은 문법 에러.

선언과 타입
자바스크립트는 변수 선언에서 타입을 지정하지 않는다. 따라서 자바스크립트의 변수는 어떤 타입의 값이든 가질 수 있다.

let i = 10;
i = "then";

10.2 var를 사용한 변수 선언

ES6 전의 자바스크립트에서는 변수를 선언하는 방법이 var 키워드 하나뿐이었으며 상수를 선언하는 방법은 없었다.

// var의 문법은 let과 동일하다.
var x;
var data = [], count = data.length;
for(var i = 0; i < count; i++) console.log(data[i]);

varlet의 차이점

  • var로 선언한 변수는 블록 스코프를 같지 않는다.
    이 변수는 얼마나 깊이 중첩됐든 관계없이 포함하는 함수 바디를 스코프를 가진다.

  • 함수 바디 바깥에서 var를 사용하면 전역 변수로 선언된다.
    하지만 var로 선언된 전역 변수와 let으로 선언된 전역 변수에는 중요한 차이가 있다.
    var로 선언된 전역 변수는 전역 객체의 프로퍼티로 존재한다. 전역 객체는 globalThis로 참조할 수 있다.
    따라서 함수 바깥에서 var x = 2;globalThis.x = 2;와 같은 의미이다.
    하지만 이는 명백하지 않은데 var로 선언된 변수는 delete 연산자로 삭제할 수 없기 때문이다.
    letconst로 선언한 전역 변수와 상수는 전역 객체의 프로퍼티가 아니다.

  • let 선언과 달리 var는 같은 변수를 몇 번이고 선언할 수 있다.
    var 변수는 블록 스코프가 아니라 함수 스코프를 가지므로, 다시 선언하는 일이 종종 있다.
    변수 i는 정수 값에 자주 사용되며, 특히 for 루프의 인덱스 변수로 자주 사용된다.
    for 루프를 여러개 쓰는 함수에서는 각 루프가 for(var i = 0; ...)로 시작하는 일이 흔하다.
    var 변수의 스코프는 루프 바디가 아니므로 각 루프에서 같은 변수를 다시 선언하고 다시 초기화해도 문제 없다.

  • var 선언에서 가장 생소한 특징은 호이스팅이라는 기능이다.
    var로 변수를 선언하면 이 선언문은 함수의 맨 위로 끌어올려진다.
    변수의 초기화는 코드상의 위치에 그대로 존재하지만 정의만 함수 맨 위로 올라가는 것이다.
    따라서 var로 선언한 변수는 함수 어디에서든 에러 없이 사용할 수 있다.
    초기화 코드가 실행되기 전이라면 변수의 값이 undefined일 수는 있지만, 초기화 하기 전에 사용한다고 해서 에러가 발생하지는 않는다.
    이러한 특징은 버그의 원인이 될 수 있으며, ES6 이후에 let으로 수정한 중요한 결점 중 하나이다.

10.3 분해 할당

ES6에서는 선언과 할당을 합친 일종의 복합 문법을 도입했으며 이를 분해 할당(destructuring assignment)라고 한다.

분해 할당에서 할당 연산자의
오른쪽에 있는 값은 배열이나 객체 같은 구조적인 값이며
왼쪽에 있는 값은 하나 이상의 변수 이름이며 배열이나 객체 리터럴 문법을 쓴다.

분해 할당이 일어나면 오른쪽 값에서 하나 이상의 값을 추출(분해)해서 왼쪽에 있는 변수에 할당한다.
분해 할당은 const, let, var 선언문의 일부로 변수로 초기화하기 위해 사용하는 경우가 대부분이지만,
일반적인 할당 표현식에서도 사용할 수 있다.

// 배열을 사용한 단순한 분해 할당 예제
let [x, y] = [1, 2];		// let x = 1, y = 2;	
[x, y] = [x +1, y + 1];		// 	x = x + 1, y = y + 1;
[x, y] = [y, x];			// 	두 변수의 값을 바꾼다.
[x, y];						// 	3,2; 

분해 할당을 활용하면 배열을 반환하는 함수를 아주 쉽게 사용할 수 있다.

// [x, y] 좌표를 [r, theta] 극좌표로 변환
function toPolar(x, y) {
	return [Math.sqrt(x * x + y * y), Math.atan2(y, x)];
}

// 극좌표를 카르테시안 좌표로 변환
function toCartesian(r, theta) {
	return [r * Math.cos(theta), r * Math.sin(theta)];
}

let [r, theta] = toPolar(1.0, 1.0);		// r == Math.sqr(2); theta == Math.PI/4
let [x, y] = toCartesian(r, theta);		// [x, y] == [1.0, 1.0]

루프에서도 분해 할당을 사용할 수 있다.

// 객체의 프로퍼티 전체의 이름-값 쌍을 순회하며 분해 할당을 통해 각 쌍을 요소가 두 개 있는 배열에서 개별 변수로 변환
let o = {x : 1, y : 2};			// 순회할 객체
for(const [name, value] of Object.entries(o)) {
	console.log(name, value);	// "x 1", "y 2"
}

분해 할당에서 왼쪽에 있는 변수 숫자와 오른쪽에 있는 값 숫자가 꼭 일치할 필요는 없다.
왼쪽의 변수가 남아있으면 undefined가 할당되고,
오른쪽의 값이 남으면 무시된다.
왼쪽의 변수 리스트에 콤마를 추가로 넣어 값 일부를 무시할 수 있다.

let [x, y] = [1];			// x == 1; y == undefined;
[x, y] = [1, 2, 3];			// x == 1; y ==2;
[, x, , y] = [1, 2, 3, 4];	// x == 2; y == 4

아래와 같이 마지막 변수 이름 앞에 점 세 개(...)를 사용해 배열을 분해하고 남은 값을 변수 하나에 모을 수 있다.

let [x, ...y] = [1, 2, 3, 4];	// x == 1; y == [2, 3, 4];

분해 할당은 중첩된 배열에도 사용할 수 있다.
이런 경우 왼쪽은 중첩된 배열 리터럴 형태여야 한다.

let [a, [b, c]] = [1, [2, 2.5], 3];		// a == 1; b == 2; c == 2.5;

배열 분해에 꼭 배열만 써야 되는 것은 아니다.
분해 할당의 오른쪽에는 이터러블 객체면 무엇이든 쓸 수 있다.
즉, for/of 루프에 사용할 수 있는 객체는 분해 할당 역시 가능하다.

let [first, ...rest] = "Hello";		// first == "H"; rest == ["e", "l", "l", "o"];

객체도 분해 할당할 수 있다.
이런 경우 왼쪽은 객체 리터럴처럼 중괄호 안에 변수 이름을 콤마로 구분한 형태여야 한다.

let transparent = {r : 0.0, g : 0.0, b : 0.0, a : 1.0}; 
let {r, g, b} = transparent;	// r == 0.0; g == 0.0; b == 0.0;
// Math 객체의 함수를 변수에 복사.
// const sin = Math.sin, cos = Math.cos, tan = Math.tan; 과 같다.
const {sin, cos, tan} = Math;

위 예제의 Math의 프로퍼티 이름이 아닌 변수가 있었다면 그 변수에는 undefinde가 할당됨.

객체를 분해하는 예제에서 변수 이름은 분해하는 객체의 프로퍼티 이름과 일치하게 정했는데,
반드시 이렇게 작성해야하는 것은 아니다.
객체 분해 할당의 왼쪽에 있는 각 식별자에 아래와 같이 콜론으로 구분한 식별자 쌍을 쓸 수 있다.
이 쌍의 첫번째는 분해하는 객체의 프로퍼티 이름이고, 두 번째는 그 프로퍼티의 값을 할당받을 변수 이름이다.

// const cosine = Math.cos, tangent = Math.tan; 과 같다.
const {cos : cosine, tan : tangent} = Math;

분해 할당은 아래와 같이 중첩된 객체, 객체의 배열, 배열의 객체 등에도 사용할 수 있다.

let points = [{x : 1, y : 2}, {x : 3, y : 4}];		// 좌표 객체가 두 개 있는 배열
let [{x : x1, y : y1}, {x : x2, y : y2}] = points;	// 변수 네 개로 분해
(x1 === 1 && y1 === 2 && x2 === 3 & y2 === 4)		// true;

아래와 같이 배열로 이루어진 객체 역시 분해할 수 있다.

let points = {p1 : [1, 2], p2 : [3, 4]};			// 배열 두 개가 있는 객체
let {p1 : [x1, y1], p2 : [x2, y2]} = points;		// 변수 네 개로 분해
(x1 === 1 && y1 === 2 && x2 === 3 & y2 === 4)		// true;

0개의 댓글