본문 바로가기

TIL

[TIL-174~175] 모던 자바스크립트 8~11장

8장 제어문

코드는 기본적으로 위에서 아래 방향으로 순차 실행됨. 그런데 조건에 따라 코드블록을 실행(조건문)하거나 반복적으로 실행(반복문)하도록 코드의 실행 흐름을 "제어"하는 것이 제어문.

 

8-1. 블록문

{  }

블록문이란 일반적으로 코드 블록 또는 블록이라고 부르는 것. 중괄호로 0~n개의 문을 묶은 것. 블록문은 하나의 실행 단위.

자체종결성 : 블록문은 항상 그 자체로 문이 종료됨. 따라서 다른 문과 달리 세미콜론을 붙이지 않음.

 

8-2. 조건문

불리언 값으로 평가될 수 있는 조건식이 주어져, 그 평가 결과에 따라 블록문의 실행 여부를 결정.

: 책에서 나온 위 설명은 if 문에 해당하지만 switch 문에는 적합하지 않은 것 같다.

1) if ... else문

if (조건식 1) {
  // 조건식 1이 참일 때 실행
} else if (조건식 2) {
  // 조건식 2가 참일 때 실행
} else if (조건식 3) {
  // 조건식 3가 참일 때 실행
} else {
  // 조건식 모두 거짓일 때 실행
}

조건식의 평가 결과가 true일 때 if 문의 코드 블록을, false일 때 else 문의 코드 블록을 실행함. 따라서 조건식의 평가 결과가 불리언 값이 아닌 경우, 강제로 불리언 값으로 "암묵적 타입 변환"됨.

조건식을 추가하고 싶을 땐 else if 문을 사용. if 문은 필수이지만, else 문과 else if 문은 옵션. else if 문은 여러 번 사용할 수 있음.

 

if (num < 0) console.log("음수");
else console.log("양수");

* 코드 블록의 문이 하나뿐이면 중괄호를 생략할 수 있다!

: 흔히 보지 못한 방식이지만 문법적으로 가능한 듯. 화살표 함수에서도 const hi = () => console.log("hi") 처럼 중괄호를 생략하듯이 가능한 모양.

 

삼항 조건 연산자와 차이

1) 삼항 조건 연산자는 값으로 평가되는 표현식을 만들기 때문에 변수에 할당할 수 있음. 간단한 조건에 따라 값을 결정해 변수에 할당할 경우 적합. 하지만 조건이 여러 개일 때 중첩해서 사용하기는 불편함.

2) 조건에 따라 실행할 내용이 복잡하면 if ... else 문을 사용하는 게 가독성에 좋음.

 

2) switch 문

주어진 표현식을 평가하여 그 값과 일치하는 표현식을 갖는 case 문으로 이동하여 코드 실행. 일치하는 case 문이 없을 때 default 문으로 이동. default 문은 옵션.

if 문의 조건식은 불리언 값으로 평가되지만, switch 문의 표현식은 다른 표현식과 비교할 대상이므로 문자열이나 숫자 값인 경우가 많음.

switch 문에서는 표현식 평가 결과가 일치하는 case 문으로 코드의 실행 흐름이 이동하지만, 해당 case 문 실행 후 자동으로 switch 문을 탈출하는 기능은 없음. 따라서 break 문을 사용하지 않으면 해당 코드 블록 안에서 남아있는 코드를 모두 실행함. 그럼 마지막 case 문이나, 마지막에 위치한 default 문까지 실행한 뒤 동작을 마치면서 원하는 결과를 얻지 못하게 됨.

하지만 의도적으로 break 문을 생략(폴스루)하여 여러 개의 case 문을 이어서(마지막 case 문에만 실행할 코드를 작성) 하나의 조건처럼 사용할 수 있음. 또한 default 문은 코드 블록의 맨 마지막에 위치하므로 break 문이 필요없어서 생략함.

if ... else 문보다 가독성이 더 좋은 특별한 경우가 아니라면 굳이 switch 문을 사용하지 않음...

 

8-3. 반복문

조건식의 평가 결과가 참일 때 코드 블록을 실행. 실행을 마친 뒤 다시 조건식을 평가하여 참일 때 코드 블록을 실행하기를 반복함. 조건식이 거짓이면 반복을 멈춤.

 

1) for 문

for (변수 선언문 또는 할당문; 조건식; 증감식) {
  // 조건식이 참일 때 반복 실행될 문;
}

일반적으로 변수 선언문의 변수는 i를 사용함. 선언문 또는 할당문에서는 i를 초기화하는 셈. 코드 블록을 반복할지 판단할 조건식에 i가 들어감. 증감식은 코드 블록이 실행된 후 실행됨.

변수 선언문, 조건식, 증감식 모두 옵션. 전부 선언하지 않으면 무한루프.

중첩 for 문 : for 문 안에 for 문을 중첩.

 

2) while 문

조건식의 평가 결과가 참이면 코드 블록을 계속해서 반복. for 문에 있는 변수 선언문과 증감식이 없음. 따라서 for 문과 달리, 반복횟수가 불명확할 때 사용.

조건식의 평가 결과가 항상 참이면 무한루프. 탈출하려면 while 문 내에 if 문으로 탈출 조건을 만들어 break 문으로 탈출시키면 됨.

 

3) do ... while 문

선 코드 블록 실행, 후 조건식 평가. 따라서 코드 블록이 무조건 한 번 이상 실행됨.

 

4) break 문

레이블 문, 반복문, switch 문의 코드 블록을 탈출시켜줌. 이외의 상황에서 사용하면 SyntaxError 발생.

* 레이블 문 : 식별자가 붙은 문.   예) switch 문의 case 문과 default 문.

코드 블록에 이름을 붙여, 코드의 실행 순서를 제어하는 것. break 문에 레이블 식별자를 붙이면 해당 레이블 문을 탈출함. 중첩 for 문에서 내부 for 문에 break 문을 써서 외부 for 문을 탈출하고 싶을 때, 외부 for 문에 레이블(식별자)을 달아주는 방식으로 사용. 이외의 경우 굳이 사용하지 않는 것 권장.

 

5) continue 문

반복문의 코드 블록 실행을 중단하고 증감식으로 실행 흐름을 이동시킴. break 문은 아예 반복문을 탈출시킨다면, continue 문은 반복문의 이번 회차만 탈출시키는 것. 특정 조건에만 실행할 코드를 남겨두고 이번 회차의 반복문을 종료할 때 유용.

 

 

9장 타입 변환과 단축 평가

9-1. 타입 변환

자바스크립트의 값은 타입이 있는데, 이 타입을 바꿀 수 있음.

1) 명시적 타입 변환 / 타입 캐스팅 : 개발자가 의도적으로 값의 타입을 변환. toString() 메서드를 사용하여 숫자를 문자열로 변환하는 등.

2) 암묵적 타입 변환 / 타입 강제 변환 : 표현식을 평가하면서 자바스크립트 엔진이 암묵적으로 타입을 자동 변환. 명시적 타입 변환과 달리 개발자의 의도가 명백히 드러나지 않아, 오류를 일으킬 수 있음. 따라서 평가 결과가 예측 가능해야 함.

원시 값은 변경 불가능하므로 타입 변환이 일어날 때, 새로운 원시 값이 생성됨. x=10일 때 x + ""을 평가한다면, x 변수의 값은 그대로 두고 새로운 문자열 값 "10"을 생성하여 "10" + ""을 평가함.

 

9-2. 암묵적 타입 변환

자바스크립트 엔진이 코드의 문맥을 고려해 데이터 타입을 강제 변환. 에러를 발생시키지 않게 해줌.

 

1) 문자열 타입으로 변환

  1. 문자열 연결 연산자(+)가 동작할 때, 피연산자는 모두 문자열 타입이어야 해서 변환.
    • 숫자를 문자열로 바꾸고 싶을 때 10 + "".
    • 배열 + ""를 하면 요소들이 콤마로 연결된 채 문자열로 변환되어서 유용. array.join()한 것과 같음.
  2. 템플릿 리터럴에 삽입된 ${표현식}도 평가 결과를 문자열 타입으로 변환.

 

2) 숫자 타입으로 변환

  1. 산술 연산자(-, *, /)의 피연산자는 모두 숫자 타입이어야 해서 변환.
    • 피연산자를 숫자로 변환할 수 없으면 그 표현식은 NaN으로 평가됨.
  2. 비교 연산자(>, <)는 크기를 비교하기 위해 피연산자를 숫자 타입으로 변환.
  3. + 단항 연산자 : 숫자 + ""이 문자열로 변환했듯, + 피연산자를 숫자로 변환.

 

3) 불리언 타입으로 변환

  1. 조건식은 불리언으로 평가되어야 하는 표현식. 불리언 값이 아닌 경우 truthy 값, falsy 값으로 구분되는데, 이걸 불리언 타입으로 변환함.
    • falsy 값에는 false 외에 undefined, null, 0/-0, NaN, ""가 있음.
  2. !표현식 : 표현식에 !를 붙이면 truthy, falsy 여부의 반대 불리언 값으로 평가됨. !!를 붙이면 truthy, falsy에 따른 불리언 값으로 평가됨.

 

9-3. 명시적 타입 변환

1) 표준 빌트인 생성자 함수(String, Number, Boolean)을 new 연산자 없이 호출, 2) 빌트인 메서드 사용, 3) 암묵적 타입 변환 이용.

* 생성자 함수나 메서드는 쓰면 되고, 위에서 다룬 암묵적 타입 변환 이용 방법 정리

  1. 문자열 타입으로 변환 : 문자열 연결 연산자(+)
  2. 숫자 타입으로 변환 : + 단항 산술 연산자, * 산술 연산자
  3. 불리언 타입으로 변환 : ! 부정 논리 연산자 두 번 사용

 

9-4. 단축 평가

표현식을 평가하는 도중 평가 결과가 확정된 경우, 나머지 평가 과정 생략하는 것.

1) 논리 연산자 사용

&&(논리곱) : 두 피연산자가 모두 참이어야 함. 따라서 두 번째 피연산자까지 평가해야 전체 표현식 평가 가능. 첫번째 피연산자가 참이어서 두번째 피연산자를 평가하는 경우, 평가 결과를 결정하는 두 번째 피연산자를 그대로 반환함.

* 리액트 JSX에서 조건부 렌더링에 자주 쓰는 문법. if 문 대체 가능.

객체를 가리킬 것으로 예상되는 변수가 null/undefined 인지 확인하여 프로퍼티 참조할 때, object && object.value라고 하면 object가 value라는 프로퍼티를 갖지 않아서 발생할 에러를 방지할 수 있음.

||(논리합) : 둘 중 하나만 참이어도 됨. 첫번째 피연산자가 참이면, 첫번째 피연산자를 그대로 반환함.

함수의 매개변수에 인수를 전달하지 않아 undefined가 할당될 때를 대비하여 기본값을 설정할 수 있음. var val = argument || "";라고 하면, argument가 undefined일 때 빈 문자열이 대신 할당될 것.

* ES6에서는 const getString = (str = "") => str; 의 방식으로 매개변수의 기본값을 설정할 수 있음.

2) 옵셔널 체이닝 연산자 (?.)

?.는 좌항이 null/undefined일 때 undefined를 반환하고, 그렇지 않을 때만 우항의 프로퍼티 참조를 이어나감. &&를 보완하는 기능. &&좌항이 0이나 ""라도 falsy 값이기 때문에 우항을 실행하지 않는 문제가 있음.