본문 바로가기

기록/코드잇 스프린트 스터디

[824 스터디] JS 3주차 | 연산자 / 제어문 / 타입 변환과 단축 평가

 
모던 자바스크립트 Deep Dive
웹페이지의 단순한 보조 기능을 처리하기 위한 제한적인 용도로 태어난 자바스크립트는 과도하다고 느껴질 만큼 친절한 프로그래밍 언어입니다. 이러한 자바스크립트의 특징은 편리한 경우도 있지만 내부 동작을 이해하기 어렵게 만들기도 합니다. 하지만 자바스크립트는 더 이상 제한적인 용도의 프로그래밍 언어가 아닙니다. 오랜 변화를 거쳐 이제 자바스크립트는 프런트엔드와 백엔드 영역의 프로그래밍 언어로 사용할 수 있는 명실상부한 범용 애플리케이션 개발 언어로 성장했습니다. 따라서 자바스크립트를 학습하는 방식도 이에 걸맞게 변화해야 하며, 이 책은 자바스크립트의 기본 개념과 동작 원리를 깊이 있게 학습하고자 하는 독자를 위해 기획되었습니다. 《모던 자바스크립트 Deep Dive》에서는 자바스크립트를 둘러싼 기본 개념을 정확하고 구체적으로 설명하고, 자바스크립트 코드의 동작 원리를 집요하게 파헤칩니다. 따라서 여러분이 작성한 코드가 컴퓨터 내부에서 어떻게 동작할 것인지 예측하고, 명확히 설명할 수 있도록 돕습니다. 또한 최신 자바스크립트 명세를 반영해 안정적이고 효율적인 코드를 작성할 수 있는 기본기를 다지고, 실전에서 쓰이는 모던 자바스크립트 프레임워크나 도구를 완벽하게 이해하고 활용할 수 있게 도와줍니다.
저자
이웅모
출판
위키북스
출판일
2020.09.25

7장 연산자

연산자는 하나 이상의 표현식을 대상으로 산술, 할당, 비교, 논리, 타입, 지수 연산 등을 수행해 하나의 값을 만든다. 이때 연산의 대상을 피연산자라 한다. 피연산자는 값으로 평가될 수 있는 표현식이어야 한다. 그리고 피연산자와 연산자의 조합으로 이뤄진 연산자 표현식도 값으로 평가될 수 있는 표현식이다.

// 산술 연산자
5 * 4 // 20

// 문자열 연결 연산자
'My name is ' + 'Lee' // "My name is Lee"

// 할당 연산자
var color = 'red'; // "red"

// 비교 연산자
3 > 5 // false

// 논리 연산자
(5 > 3) && (2 < 4)  // true

// 타입 연산자
typeof 'Hi' // "string"

7.1 산술 연산자

이항 산술 연산자는 2개의 피연산자를 산술 연산하여 숫자 값을 만든다. 모든 이상 산술 연산자는 어떤 산술 연산을 해도 피연산자의 값이 바뀌는 경우는 없고 언제나 새로운 값을 만들 뿐이다.

 

단항 산술 연산자는 1개의 피연산자를 산술 연산하여 숫자 값을 만든다. 주의할 점은 증가/감소(++/--) 연산자는 피연산자의 값을 변경하는 부수 효과가 있다는 점이다.

 

문자열 연결 연산자는 피연산자 중 하나 이상이 문자열인 경우 문자열 연결 연산자로 동작한다.

7.2 할당 연산자

할당 연산자는 좌항의 변수에 값을 할당하므로 변수 값이 변하는 부수 효과가 있다.

할당문은 값으로 평가되는 표현식인 문으로서 할당된 값으로 평가된다. 따라서 다음과 같이 할당문을 다른 변수에 할당할 수도 있다.

var x, y;
y = x = 10; // 연쇄 할당
console.log(x, y); // 10 10

7.3 비교 연산자

동등 비교(==) 연산자는 좌항과 우항의 피연산자를 비교할 때 먼저 암묵적 타입 변환을 통해 타입을 일치시킨 후 같은 값인지 비교한다.

일치 비교(===) 연산자는 좌항과 우항의 피연산자가 타입도 같고 값도 같은 경우에 한하여 true를 반환한다.

7.4 삼항 조건 연산자

삼항 조건 연산자는 조건식의 평가 결과에 따라 반환할 값을 결정하고 부수 효과는 없다. 다음과 같이 사용한다.

조건식 ? 조건식이 ture일때 반환할 값 : 조건식이 false일때 반환할 값
var x = 2;

// x가 짝수이면 '짝수'를 홀수이면 '홀수'를 반환한다.
// 2 % 2는 0이고 0은 false로 암묵적 타입 변환된다.
var result = x % 2 ? '홀수' : '짝수';

console.log(result); // 짝수

 

if ... else문을 사용해도 삼항 조건 연산자 표현식과 유사하게 처리할 수 있지만 삼항 조건 연산자 표현식은 값처럼 사용할 수 있고 if ... else 문은 값처럼 사용할 수 없다.

7.5 논리 연산자

논리 연산자는 우항과 좌항의 피연산자(부정 논리 연산자의 경우 우항의 피연산자)를 논리 연산한다.

논리 연산자 의미 부수 효과
|| 논리합(OR) X
&& 논리곱(AND) X
! 부정(NOT) X

 

8장 제어문

8.1 블록문

블록문은 0개 이상의 문을 중괄호로 묶은 것으로, 코드 블록 또는 블록이라고 부른다. 제어문이나 함수를 정의할 때 사용하는 것이 일반적이다.

8.2 조건문

8.2.1 if문

if문은 주어진 조건식의 평가 결과에 따라 실행할 코드 블록을 결정한다. 조건식의 평가 결과가 true일 경우 if문의 코드 블록이 실행되고 false일 경우 else문의 코드 블록이 실행된다.

 

8.2.2 switch문

switch문은 주어진 표현식을 평가하여 그 값과 일치하는 표현식을 갖는 case문으로 실행 흐름을 옮긴다. case문은 상황을 의미하는 표현식을 지정하고 그 뒤에 실행할 문들을 위치시킨다.

break문은 코드 블록에서 탈출하는 역할을 한다. break문이 없다면 case문의 표현식과 일치하지 않더라도 실행 흐름이 다음 case문으로 연이어 이동한다.

8.3 반복문

8.3.1 for문

for문은 조건식이 거짓으로 평가될 때까지 코드 블록을 반복 실행한다. 다음과 같이 사용한다.

for (초기화식; 조건식; 증감식) {
  조건식이 참인 경우 반복 실행될 문;
}

 

위 예제의 for 문은 변수 i가 0으로 초기화된 상태에서 시작하여 i가 2보다 작을 때까지 코드 블록을 2번 반복 실행한다.

  1. for 문을 실행하면 가장 먼저 초기화식 var i = 0이 실행된다. 초기화식은 단 한번만 실행된다.
  2. 초기화식의 실행이 종료되면 조건식으로 실행 순서가 이동한다. 현재 변수 i는 0이므로 조건식의 평가 결과는 true다.
  3. 조건식의 평가 결과가 true이므로 실행 순서가 코드 블록으로 이동하여 실행된다. 증감문으로 실행 순서가 이동하는 것이 아니라 코드 블록으로 실행 순서가 이동하는 것에 주의하자.
  4. 코드 블록의 실행이 종료하면 증감식으로 실행 순서가 이동한다. 증감식 i++가 실행되어 i는 1이 된다.
  5. 증감식 실행이 종료되면 다시 조건식으로 실행 순서가 이동한다. 초기화식으로 실행 순서가 이동하는 것이 아니라 조건식으로 실행 순서가 이동하는 것에 주의하자. 초기화식은 단 한번만 실행된다. 현재 변수 i는 1이므로 조건식의 평가 결과는 true다.
  6. 조건식의 평가 결과가 true이므로 실행 순서가 코드 블록으로 이동하여 실행된다.
  7. 코드 블록의 실행이 종료하면 증감식으로 실행 순서가 이동한다. 증감식 i++가 실행되어 i는 2가 된다.
  8. 증감식 실행이 종료되면 다시 조건식으로 실행 순서가 이동한다. 현재 변수 i는 2이므로 조건식의 평가 결과는 false다. 조건식의 평가 결과가 false이므로 for 문의 실행이 종료된다.

8.3.2 while문

while문은 주어진 조건식의 평가 결과가 참이면 코드 블록을 계속해서 반복 실행한다.

var count = 0;

// count가 3보다 작을 때까지 코드 블록을 계속 반복 실행한다.
while (count < 3) {
  console.log(count);
  count++;
} // 0 1 2

9장 타입 변환과 단축 평가

9.1 타입 변환이란?

개발자가 의도적으로 값의 타입을 변환하는 것을 명시적 타입 변환 또는 타입 캐스팅이라 하고 자바스크립트 엔진에 의해 암묵적으로 타입이 변환되는 것을 암묵적 타입 변환 또는 타입 강제 변환이라 한다.

 

명시적 타입 변환이나 암묵적 타입 변환이 기존 원시 값을 직접 변경하는 것은 아니라 원시 값은 변경 불가능한 값이므로 변경할 수 없고 타입 변환이란 기존 원시 값을 사용해 다른 타입의 새로운 원시 값을 생성하는 것이다.

 

자신이 작성한 코드에서 암묵적으로 타입 변환이 발생하는지, 발생한다면 어떤 타입의 어떤 값으로 변환되는지, 그리고 타입 변환된 값으로 표현식이 어떻게 평가될 것인지 예측 가능해야 한다.

9.2 암묵적 타입 변환

9.2.1 문자열 타입으로 변환

자바스크립트 엔진은 문자열 연결 연산자 표현식을 평가하기 위해 문자열 연결 연산자의 피연산자 중에서 문자열 타입이 아닌 피연산자를 문자열 타입으로 암묵적 타입 변환한다. 다음과 같이 동작한다.

// 숫자 타입
0 + ''              // "0"
-0 + ''             // "0"
1 + ''              // "1"
-1 + ''             // "-1"
NaN + ''            // "NaN"
Infinity + ''       // "Infinity"
-Infinity + ''      // "-Infinity"
// 불리언 타입
true + ''           // "true"
false + ''          // "false"
// null 타입
null + ''           // "null"
// undefined 타입
undefined + ''      // "undefined"
// 심볼 타입
(Symbol()) + ''     // TypeError: Cannot convert a Symbol value to a string
// 객체 타입
({}) + ''           // "[object Object]"
Math + ''           // "[object Math]"
[] + ''             // ""
[10, 20] + ''       // "10,20"
(function(){}) + '' // "function(){}"
Array + ''          // "function Array() { [native code] }"

 

9.2.2 숫자 타입으로 변환

자바스크립트 엔진은 산술 연산자 표현식을 평가하기 위해 산술 연산자의 피연산자 중에서 숫자 타입이 아닌 피연산자를 숫자 타입으로 암묵적 타입 변환한다. 이때 피연산자를 숫자 타입으로 변환할 수 없는 경우는 산술 연산을 수행할 수 없으므로 표현식의 평가 결과는 NaN이 된다. 다음과 같이 동작한다.

// 문자열 타입
+''             // 0
+'0'            // 0
+'1'            // 1
+'string'       // NaN
// 불리언 타입
+true           // 1
+false          // 0
// null 타입
+null           // 0
// undefined 타입
+undefined      // NaN
// 심볼 타입
+Symbol()       // TypeError: Cannot convert a Symbol value to a number
// 객체 타입
+{}             // NaN
+[]             // 0
+[10, 20]       // NaN
+(function(){}) // NaN

 

9.2.3 불리언 타입으로 변환

자바스크립트 엔진은 if문이나 for문과 같은 제어문 또는 삼항 조건 연산자의 조건식을 평가하기 위해 불리언 타입이 아닌 값을 Truthy 값 또는 Falsy 값으로 구분한다. 다음과 같이 동작한다.

// 주어진 인자가 Falsy 값이면 true, Truthy 값이면 false를 반환한다.
function isFalsy(v) {
  return !v;
}

// 주어진 인자가 Truthy 값이면 true, Falsy 값이면 false를 반환한다.
function isTruthy(v) {
  return !!v;
}

// 모두 true를 반환한다.
console.log(isFalsy(false));
console.log(isFalsy(undefined));
console.log(isFalsy(null));
console.log(isFalsy(0));
console.log(isFalsy(NaN));
console.log(isFalsy(''));

console.log(isTruthy(true));
// 빈 문자열이 아닌 문자열은 Truthy 값이다.
console.log(isTruthy('0'));
console.log(isTruthy({}));
console.log(isTruthy([]));

9.3 명시적 타입 변환

9.3.1 문자열 타입으로 변환

문자열 타입이 아닌 값을 문자열 타입으로 변환하는 방법은 다음과 같다.

  1. String 생성자 함수를 new 연산자 없이 호출하는 방법
  2. Object.prototype.toString 메소드를 사용하는 방법
  3. 문자열 연결 연산자를 이용하는 방법

9.3.2 숫자 타입으로 변환

숫자 타입이 아닌 값을 숫자 타입으로 변환하는 방법은 다음과 같다.

  1. Number 생성자 함수를 new 연산자 없이 호출하는 방법
  2. parseInt, parseFloat 함수를 사용하는 방법(문자열만 변환 가능)
  3. 단항 연결 연산자를 이용하는 방법
  4. 산술 연산자를 이용하는 방법

9.3.3 불리언 타입으로 변환

불리언 타입이 아닌 값을 불리언 타입으로 변환하는 방법은 다음과 같다.

  1. Boolean 생성자 함수를 new 연산자 없이 호출하는 방법
  2. ! 부정 논리 연산자를 두번 사용하는 방법

9.4 단축 평가

9.4.1 논리 연산자를 사용한 단축 평가

논리합 연산자는 두 개의 피연산자 중 하나만 true로 평가되어도 true를 반환한다. 첫 번째 피연산자가 true라면 논리 연산의 결과를 결정한 첫 번째 피연산자를 그대로 반환한다.

 

논리곱 연산자는 두 개의 피연산자가 모두 true로 평가될 때 true를 반환한다. 첫 번째 피연산자가 true여도 표현식을 평가할 수가 없어 두 번째 피연산자까지 평가해야 한다. 이때 논리 연산의 결과를 결정하는 두 번째 피연산자를 그대로 반환한다.

 

논리곱, 논리합 연산자는 논리 연산의 결과를 결정하는 피연산자를 타입 변환하지 않고 그대로 반환한다. 이를 단축 평가라 한다. 단축 평가는 표현식을 평가하는 도중에 평가 결과가 확정된 경우 나머지 평가 과정을 생략하는 것을 말한다.

단축 평가 표현식 평가 결과
true || any true
false || any any
true && any any
false && any false

 

단축 평가는 다음 상황에 사용하면 에러를 방지할 수 있다.

  1. 객체를 가리키기를 기대하는 변수가 null 또는 undefined가 아닌지 확인하고 프로퍼티를 참조할 때
  2. 함수 매개변수에 기본값을 설정할 때

9.4.2 옵셔널 체이닝 연산자

옵셔널 체이닝 연산자 ?.는 좌항의 피연산자가 null 또는 undefined인 경우 undefined를 반환하고, 그렇지 않으면 우항의 프로퍼티 참조를 이어간다. 하지만 false 값이라도 null 또는 undefined이 아니기 때문에 우항의 프로퍼티 참조를 이어간다.

 

9.4.3 null 병합 연산자

null 병합 연산자 ??는 좌항의 피연산자가 null 또는 undefined인 경우 우항의 피연산자를 반환하고, 그렇지 않으면 좌항의 피연산자를 반환한다. null 병합 연산자 ??는 변수에 기본값을 설정할 때 유용하다. 하지만 false 값이라도 null 또는 undefined이 아니기 때문에 좌항의 피연산자를 그대로 반환한다.