자바스크립트 기본 - 문법

자바스크립트 기본 문법을 살펴봅니다.

모던 마크업

  • type 속성: <script type=...> HTML4 에서는 스크립트에 type 을 명시하는 것이 필수였습니다. 따라서 type="text/javascript" 속성이 붙은 스크립트를 어렵지 않게 찾을 수 있었는데 이제는 타입 명시가 필수가 아닙니다. 게다가 모던 HTML 표준에서는 이 속성의 의미가 바뀌었습니다.

  • language 속성: <script language=...> 이 속성은 현재 사용하고 있는 스크립트 언어를 나타냅니다. 지금은 자바스크립트가 기본 언어이므로 사용할 필요가 없어졌습니다.

  • 스크립트 전후에 위치한 주석

<script type="text/javascript"><!--
    ...
//--></script>

태그 옆에 붙은 주석은 <script> 태그를 처리하지 못하는 브라우저가 해당 스크립트를 읽지 못하게 하려고 사용했었습니다. 하지만 지난 15년간 출시된 브라우저는 <script> 태그를 처리할 수 있으므로, 모던 자바스크립트에선 이런 트릭을 사용하지 않습니다.

외부 스크립트

복수의 스크립트를 HTML에 삽입하고 싶다면 스크립트 태그를 여러 개 사용하면 됩니다.

<script src="/js/script1.js"></script>
<script src="/js/script2.js"></script>

주의:

HTML 안에 직접 스크립트를 작성하는 방식은 대개 스크립트가 아주 간단할 때만 사용합니다.

스크립트를 별도의 파일에 작성하면 브라우저가 스크립트를 다운받아 캐시에 저장하기 때문에, 성능상의 이점이 있습니다.

여러 페이지에서 동일한 스크립트를 사용하는 경우, 브라우저는 페이지가 바뀔 때마다 스크립트를 새로 다운받지 않고 캐시로부터 스크립트를 가져와 사용합니다. 따라서 스크립트 파일을 한 번만 다운받게 됩니다.

이를 통해 트래픽이 절약되고 웹 페이지의 실제 속도가 빨라집니다.

src 속성이 있으면 태그 내부의 코드는 무시됩니다.

코드 구조

문(statement)은 어떤 작업을 수행하는 문법 구조(syntax structure)와 명령어(command)를 의미합니다. 코드에 원하는 만큼 문을 작성할 수 있으며, 서로 다른 문은 세미콜론으로 구분합니다.

alert('Hello'); alert('World');

코드의 가독성을 위해 각 문은 서로 다른 줄에 작성하는 것이 일반적입니다.

alert('Hello');
alert('World');

세미콜론

줄 바꿈이 있다면 세미콜론(semicolon)을 생략할 수 있습니다.

alert('Hello')
alert('World')

자바스크립트는 줄 바꿈이 있으면 이를 '암시적'으로 세미콜론으로 해석합니다. 이런 동작 방식을 세미콜론 자동 삽입(automatic semicolon insertion)이라 부릅니다. 하지만 줄바꿈이 항상 세미콜론을 의미하진 않습니다.

alert(3 +
1
+ 2);

세미콜론 자동 삽입이 일어나지 않았기 때문에 6 이 출력됩니다. 반면, 세미콜론이 정말로 필요하지만 자바스크립트가 이를 추정하지 '못하는' 상황도 존재합니다.

에러 예제

alert("에러가 발생합니다.")
[1, 2].forEach(alert)

위 코드를 실행해보면 첫째줄의 alert 만 제대로 출력되고 에러가 발생하는 걸 확인할 수 있습니다.

에러가 발생한 이유는 세미콜론이 없을 때 자바스크립트가 대괄호 [...] 앞에는 세미콜론이 있다고 가정하지 않기 때문입니다. 따라서 자바스크립트 엔진은 다음과 같이 코드를 보게 됩니다.

alert("에러가 발생합니다.")[1,2].forEach(alert)

줄바꿈으로 문을 나눴더라도, 문 사이엔 세미콜론을 넣는 것이 좋습니다. 자바스크립트 커뮤니티에서도 이를 규칙으로 정해 권장하고 있습니다.

주석

 // 한 줄짜리 주석입니다.
 /* 두 줄 이상 주석입니다.
 이렇게 여러 줄을 작성할 수 있죠.
 */
 alert("주석은 자바스크립트 엔진에서 무시합니다.");

중첩 주석은 지원하지 않습니다.

/*
  /* 중첩 주석 : 에러 발생 */
*/
alert('World');

주석 달기를 두려워하지 마세요.

주석을 달면 코드의 전체적인 길이가 증가하지만 이는 전혀 문제가 되지 않습니다. 프로덕션 서버에 배포하기 전에 코드를 압축해주는 도구가 많이 있고, 이 도구들은 주석을 삭제해주기 때문입니다. 실행 중인 스크립트엔 주석이 들어가지 않으므로, 주석은 최종으로 배포되는 코드에 부정적인 영향을 끼치지 않습니다.

엄격 모드

자바스크립트는 ECMAScript5(ES5)가 등장하기 전인 2009년까지는 기존의 자바스크립트 기능을 변경하지 않으면서 새로운 기능을 추가해 호환성 이슈 없이 발전해왔습니다. 하지만 자바스크립트 창시자들이 했던 실수나 불완전한 결정이 언어 안에 영원히 박제된다는 단점도 생겼습니다.

ES5 등장 이후 새로운 기능이 추가되고 기존 기능이 변경 되면서 하위 호환성 문제가 발생할 수 있어 ES5의 기본 모드에선 활성화되지 않도록 설계했고 use strict 라는 특별한 지시자를 사용해 엄격 모드(strict mode)를 활성화 했을 때만 이 변경사항이 적용될 수 있게 해놓았습니다.

use strict

지시자 "use strict" 혹은 'use strict' 는 단순한 문자열처럼 생겼으나 스크립트 최상단에 이를 작성하면 스크립트 전체가 모던한 방식으로 작동합니다. 스크립트 최상단뿐 아니라 함수 구현부 맨 앞에 올 수도 있습니다. 이렇게 하면 오직 해당 함수만 엄격 모드로 실행됩니다.

use strict 를 취소할 방법은 없습니다.

일단 엄격 모드가 적용되면 돌이킬 방법은 없습니다.

브라우저 콘솔

개발한 기능을 테스트하기 위해 브라우저 콘솔을 사용하는 경우, 기본적으로 use strict 가 적용되어 있지 않는다는 점에 주의해야 합니다. 그렇다면 어떻게 해야 콘솔에서 use strict 를 사용할 수 있을까요? 아래와 같이 사용하면 가능합니다.

'use strict';
// ... 테스트하려는 코드 입력
<Enter  눌러 실행>

'use strict' 꼭 사용해야 하나요

모던 자바스크립트는 '클래스'와 '모듈'이라 불리는 진일보한 구조를 제공합니다. 그리고 이 둘을 사용하면 use strict 가 자동으로 적용됩니다. 따라서 이 둘을 사용하고 있다면 스크립트에 "use script" 를 작성하지 않아도 됩니다.

변수와 상수

변수

let user = 'john', age = 25, message = 'Hello';

위 코드와 같이 한 줄에 여러 변수를 선언하는 것도 가능하지만 권장하는 방법은 아닙니다. 가독성을 위해 한 줄에 하나의 변수를 작성합시다.

변수 명명 규칙

변수 명명 시 두 가지 제약 사항이 있습니다.

  1. 변수명에는 오직 문자와 숫자, 그리고 기호 $_ 만 들어갈 수 있다.

  2. 첫 글자는 숫자가 될 수 없다.

비 라틴계 언어도 변수명에 사용할 수 있지만 권장하진 않습니다.

키릴 문자, 심지어 상형 문자도 변수명에 사용할 수 있지만 영어를 변수명에 사용하는 것이 국제적인 관습이므로 변수명은 영어를 사용하여 만들길 권유 드립니다.

use strict 없이 할당하기

변수는 대개 정의되어 있어야 사용할 수 있습니다. 그러나 예전에는 let 없이도 단순하게 값을 할당해 변수를 생성하는 것이 가능했습니다. use strict 를 쓰지 않으면 과거 스크립트와의 호환성을 유지할 수 있기 때문에 이 방식을 사용할 수 있습니다.

num = 5;
alert(num); // 5

이렇게 변수를 생성하는 것은 나쁜 관습입니다. 엄격 모드에서 에러를 발생시키기 때문이죠.

대문자 상수

상수는 const 를 사용하여 정의합니다. 그리고 '하드 코딩한' 값의 별칭을 만들 때 대문자 상수를 만듭니다.

const name = "mark";
name = "jack";

const COLOR_RED = "#F00";
let color = COLOR_RED;
alert(color); // #F00

바람직한 변수명

변수명은 간결하고, 명확해야 합니다. 변수의 이름을 짓는 것은 프로그래밍에서 가장 중요하고 복잡한 기술 중 하나입니다. 변수명만 슬쩍 봐도 초보자가 코드를 작성했는지, 노련한 개발자가 작성했는지 알 수 있습니다.

실제 프로젝트에선 맨 처음부터 완전히 독립적인 코드를 작성하기보다 기존 코드의 틀을 변경하고 확장하는데 대부분의 시간을 보냅니다. 작성했던 코드를 얼마 후에 다시 봤을 때, 정보에 알맞은 이름이 적혀있으면 정보를 더 쉽게 찾을 수 있습니다.

  • userName 이나 shoppingCart 처럼 사람이 읽을 수 있는 이름을 사용하세요.

  • 무엇을 하고 있는지 명확히 알고 있지 않을 경우 외에는 줄임말이나 a, b, c 와 같은 짧은 이름은 피하세요.

  • 최대한 서술적이고 간결하게 명명해 주세요. datavalue 는 나쁜 이름의 예시입니다. 이런 이름은 아무것도 설명해주지 않습니다. 코드 문맥상 변수가 가리키는 데이터나 값이 아주 명확할 때에만 이런 이름을 사용합시다.

  • 자신만의 규칙이나 소속된 팀의 규칙을 따르세요. 만약 사이트 방문객을 'user' 라고 부르기로 했다면, 이와 관련된 변수를 currentVisitornewManInTown 이 아닌 currentUsernewUser 라는 이름으로 지어야 합니다.

재사용 아니면 새로 만들기?

개발자 중에는 새로운 변수를 선언하기보다 기존 변수를 재사용 하는 걸 선호하는 게으른 사람들이 있습니다.

재사용된 변수는 과거에 붙여진 스티커를 떼지 않은 채 물건만 바뀐 상자와 같습니다. 상자 안에 무엇이 들어 있는지, 내용물의 정보를 알고 있는 사람이 누구인지 알 수 없습니다.

변수를 재사용하면 변수 선언에 쏟는 노력을 좀 덜 순 있겠지만, 디버깅에 열 배 더 많은 시간을 쏟아야 합니다.

변수를 추가하는 것은 악습이 아닙니다. 좋은 습관입니다.

모던 자바스크립트 압축기(minifier)와 브라우저는 최적화를 잘해줍니다. 변수를 추가한다고 해서 성능 이슈가 생기지 않죠. 값이 다른 경우, 변수를 다르게 선언해 주면 코드 최적화에 도움이 될 수 있습니다.

자료형

자바스크립트에서 값은 항상 문자열이나 숫자형 같은 특정한 자료형에 속합니다. 자바스크립트에는 여덟 가지 기본 자료형이 있으며 자바스크립트의 변수는 자료형에 관계없이 모든 데이터일 수 있습니다. 따라서 변수는 어떤 순간에 문자열일 수 있고 다른 순간엔 숫자가 될 수도 있습니다.

let message = "hello";
message = 123456;

이처럼 자료의 타입은 있지만 변수에 저장되는 값의 타입은 언제든지 바뀔 수 있는 언어를 '동적 타입(dynamically typed)' 언어라고 부릅니다.

typeof 연산자

typeof 연산자는 인수의 자료형을 반환합니다. typeof 는 두 가지 형태의 문법을 지원합니다.

  1. 연산자: typeof x

  2. 함수: typeof(x)

괄호가 있든 없든 결과가 동일합니다.

typeof undefined // "undefined"
typeof 0 // "number"
typeof 10n // "bigint"
typeof true // "boolean"
typeof "foo" // "string"
typeof symbol("id") // "symbol"
typeof Math; // "object"  
typeof null; // "object"
typeof alert; // "function"

typeof null 의 결과는 "object" 입니다. null 은 별도의 고유한 자료형을 가지는 특수 값으로 객체가 아니지만, 하위 호환성을 유지하기 위해 이런 오류를 수정하지 않고 남겨둔 상황입니다. 언어 자체의 오류이므로 null 이 객체가 아님에 유의하시기 바랍니다.

if와 '?'를 사용한 조건 처리

불린형으로의 변환

  • 숫자 0, 빈 문자열 "", null, undefined, NaN 은 불린형으로 변환 시 모두 false 가 됩니다. 이런 값들을 'falsy(거짓 같은)' 값이라고 부릅니다.

  • 이 외의 값은 불린형으로 변환 시 true 가 되므로 'truthy(참 같은)' 값이라고 부릅니다.

이 규칙에 따르면 아래의 예시 코드는 절대 실행되지 않습니다.

if (0) { // 0은 falsy입니다.
    ...
}

아래 코드는 항상 실행됩니다.

if (1) { // 1은 truthy입니다.
    ...
}

아래와 같이 확정된 불린 값을 if 문에 전달할 수도 있습니다.

let cond = (year == 2015);
if (cond) {
    ...
}

조건부 연산자 '?'

조건부 연산자는 물음표 ? 로 표시합니다. 아래 코드에서 물음표 연산자는 우선 순위가 비교 연산자인 > 보다 낮으므로 비교 연산자가 실행된 후에 실행됩니다.

let accessAllowed = age > 18 ? true : false;

괄호가 있으나 없으나 차이는 없지만 코드의 가독성을 위해 괄호를 사용할 것을 권유합니다.

let accessAllowed = (age > 18) ? true : false;

부적절한 '?'

물음표 ?if 대용으로 쓰는 경우가 종종 있습니다.

let company = prompt('자바스크립트는 어떤 회사가 만들었을까요?', '');

(company == 'Netscape') ?
    alert('정답입니다!') : alert('오답입니다!');

개발자 입장에선 if 문을 사용할 때 보다 코드 길이가 짧아진다는 점 때문에 물음표 ?if 대용으로 쓰는게 매력적일 순 있지만 이렇게 코드를 작성하면 가독성이 떨어집니다.

아래는 if 를 사용한 코드입니다.

let company = prompt('자바스크립트는 어떤 회사가 만들었을까요?', '');

if (company == 'Netscape') {
    alert('정답입니다!');
} else {
    alert('오답입니다!');
}

코드를 읽을 때 우리의 눈은 수직으로 움직입니다. 수평으로 길게 늘어진 코드보단 여러 줄로 나뉘어 작성된 코드 블록이 더 읽기 쉽습니다.

물음표 연산자 ? 는 조건에 따라 반환 값을 달리하려는 목적으로 만들어졌습니다. 이런 목적에 부합하는 곳에 물음표를 사용합시다.

논리 연산자

첫번째 truthy를 찾는 OR 연산자 '||'

자바스크립트에서만 제공하는 논리연산자 OR의 '추가'기능에 대해 알아보겠습니다. 추가 기능은 아래와 같은 알고리즘으로 동작합니다.

OR 연산자와 피연산자가 여러 개인 경우:

result = value1 || value2|| value3;

이때 OR 연산자는 다음과 같은 순서로 연산을 수행합니다.

  • 가장 왼쪽 피연산자부터 시작해 오른쪽으로 나아가며 연산을 수행합니다.

  • 각 피연산자를 불린형으로 변환합니다. 변환 후 그 값이 true 이면 연산을 멈추고 해당 피연산자의 변환 전 원래 값을 반환합니다.

  • 피연산자 모두를 평가한 경우(모든 피연산자가 false 로 평가되는 경우)엔 마지막 피연산자를 반환합니다.

여기서 핵심은 반환 값이 형 변환을 하지 않은 원래 값이라는 것입니다. 아래 예시 코드로 확인해보겠습니다.

alert(1 || 0); // truthy 인 1 반환
alert(null || 1); // truthy 인 1 반환
alert(null || 0 || 1); // truthy 인 1 반환
alert(undefined || null || 0); // 모두 falsy이므로 마지막 값인 0 반환
  1. 변수 또는 표현식으로 구성된 목록에서 첫 번째 truthy 얻기

let firstName = "";
let lastName = "";
let nickName = "바이올렛";

alert(firstName || lastName || nickName || "익명"); // 바이올렛

모든 변수가 falsy이면 "익명" 이 출력되었을 겁니다.

  1. 단락 평가

OR 연산이 truthy를 만나면 나머지 값들은 건드리지 않은 채 평가를 멈추는 프로세스를 '단락 평가'라고 합니다.

단락 평가의 동작 방식은 두 번째 피연산자가 변수 할당과 같은 부수적인 표과(side effect)를 가지는 표현식 일 때 명확히 볼 수 있습니다.

아래 예시를 실행하면 두 번째 메세지만 출력됩니다.

true || alert("not printed");
false || alert("printed");

첫 번째 줄의 || 연산자는 true 를 만나자마자 평가를 멈추기 때문에 alert 가 실행되지 않습니다. 단락 평가는 연산자 왼쪽 조건이 falsy일 때만 명령어를 실행하고자 할 때 자주 쓰입니다.

첫번째 falsy를 찾는 AND 연산자 '&&'

앞서 설명한 첫번째 truthy를 찾는 OR 연산자와 같은 방식으로 truthy가 아닌 falsy 를 찾게 되면 평가를 멈추고 변환 전 원래의 값을 반환합니다.

let firstName = "";
let lastName = "";
let nickName = "바이올렛";

alert(firstName && lastName && nickName && "익명"); // "" 빈 값 출력

&& 의 우선순위가 || 보다 높습니다.

따라서 a && b || c && d(a && b) || (c && d) 와 동일하게 동작합니다.

if 를 || 나 && 로 대체하지 마세요.

어떤 개발자들은 AND 연산자 &&if 문을 '짧게' 줄이는 용도로 사용하곤 합니다.

let x = 1;
(x > 0) && alert( '0 보다 큽니다' );

위 코드에서 (x > 0) 이 참인 경우에만 alert 문이 실행됩니다.

if 문으로 변경해보겠습니다.

let x = 1;
if (x > 0) alert( '0보다 큽니다!' );

&& 를 사용한 코드가 더 짧긴 하지만 if 문을 사용한 예시가 코드에서 무엇을 구현하고자 하는지 더 명백히 드러나고 가독성도 좋습니다.

! (NOT)

NOT 을 두 개 연달아 사용(!!) 하면 값을 불린형으로 변환할 수 있습니다.

alert(!"non-empty string"); // false
alert(!!"non-empty string"); // true

참고로 내장 함수 Boolean 을 사용하면 !! 을 사용한 것과 같은 결과를 도출할 수 있습니다.

alert(Boolean("non-empty string")); // true

NOT 연산자의 우선순위는 모든 논리 연산자 중에서 가장 높기 때문에 항상 &&|| 보다 먼저 실행됩니다.

아래 코드는 12 가 차례대로 출력됩니다.

alert(alert(1) || 2 || alert(3));

alert 메서드는 값을 반환하지 않기 때문에 undefined 를 반환합니다. 따라서 왼쪽 피연산자인 alert(1) 이 실행되고 undefined 를 반환받아 다음 피연산자인 2를 출력합니다. 2 는 truthy 이기 때문에 연산이 멈추게 됩니다.

아래 코드는 1 , undefined 를 출력합니다.

alert(alert(1) && alert(2));

왼쪽 피연산자인 alert(1) 을 실행하고 연산을 멈춥니다. alert 의 반환 값인 undefined 를 출력하고 끝이 납니다.

nullish 병합 연산자 '??'

nullish 병합 연산자(nullish coalescing operator) ?? 를 사용하면 짧은 문법으로 여러 피연산자 중 그 값이 '확정되어 있는' 변수를 찾을 수 있습니다. a ?? b 의 평가 결과는 다음과 같습니다.

  • anull 도 아니고 undefined 도 아니면 a

  • 그 외의 경우는 b

nullish 병합 연산자 ?? 없이 x = a ?? b 와 동일한 동작을 하는 코드를 작성하면 다음과 같습니다.

x = (a !== null && a !== undefined) ? a : b;

또 다른 예시로 firstName , lastName , nickName 이란 변수에 사용자 이름이나 별명을 저장하는데, 사용자가 아무런 정보도 입력하지 않는 케이스도 허용한다고 해보겠습니다.

화면엔 세 변수 중 실제 값이 있는 변수의 값을 출력하는데, 세 변수 모두 값이 없다면 '익명의 사용자'가 출력되도록 해봅시다.

let firstName = null;
let lastName = null;
let nickName = "바이올렛";

alert(firstName ?? lastName ?? nickName ?? "익명의 사용자"); // 바이올렛 출력

'??' 와 '||' 의 차이

nullish 병합 연산자는 OR 연산자 || 와 상당히 유사해 보입니다. 실제로 위 예시 코드를 || 로 바꿔도 동일한 결과를 출력합니다. 두 연산자는 다음과 같은 중요한 차이점이 있습니다.

  • || 는 첫 번째 truthy 값을 반환

  • ?? 는 첫 번째 정의된(defined) 값을 반환

nullundefined , 숫자 0 을 구분 지어 다뤄야 할 때 이 차이점은 매우 중요한 역할을 합니다.

height = height ?? 100;

height 에 값이 정의되지 않은 경우 height100 이 할당됩니다. 이제 ??|| 를 비교해봅시다.

let height = 0;
alert(height || 100); // 100
alert(height ?? 100); // 0

height || 100height 에 할당된 0 을 falsy 한 값으로 취급했기 때문에 null 이나 undefined 를 할당한 것과 동일하게 처리합니다. 따라서 결과는 100 이 됩니다. 이런 특징 때문에 높이처럼 0 이 할당될 수 있는 변수를 사용해 기능을 개발할 땐 || 보다 ?? 가 적합합니다.

연산자 우선순위

?? 의 연산자 우선순위는 5 로 꽤 낮습니다.

따라서 ??=? 보다는 먼저, 대부분의 연산자보다는 나중에 평가됩니다. 그렇기 때문에 복잡한 표현식 안에서 ?? 를 사용해 값을 하나 선택할 땐 괄호를 추가하는게 좋습니다.

let height = null;
let width = null;

let area = (height ?? 100) * (width ?? 50);

alert(area); // 5000

그렇지 않으면 *?? 보다 우선순위가 높기 때문에 * 가 먼저 실행됩니다. 결국엔 아래 예시처럼 동작합니다.

let area = height ?? (100 * width) ?? 50; // 0

?? 엔 자바스크립트 언어에서 규정한 또 다른 제약사항이 있습니다.

안정성 관련 이슈 때문에 ?? 나 || 와 함께 사용하지 못합니다.

let x = 1 && 2 ?? 3; // SyntaxError: Unexpected token '??

사람들이 ||?? 로 바꾸기 시작하면서 만드는 실수를 방지하고자 명세서에 제약이 추가된 상황입니다.

제약을 피하려면 괄호를 사용하면 됩니다.

let x = (1 && 2) ?? 3;
alert(x); // 2

'for' 반복문

구성요소 생락하기

let i = 0;

for(; i < 3; i++) alert(i); // 0, 1, 2
for(; i < 3;) alert(i++); // 0, 1, 2
for(;;) {} // 무한 반복

for 문의 구성요소를 생략할 때 주의할 점은 두 개의 ; 세미콜론을 꼭 넣어주어야 한다는 점입니다. 하나라도 없으면 문법 에러가 발생합니다.

다음 반복으로 넘어가기

for (let i = 0; i < 10; i++) {
    // 조건이 참이라면 남아있는 본문은 실행되지 않습니다.
    if (i % 2 == 0) continue;
    alert(i); // 홀수만 출력, 1 3 5 7 9
}

continue 는 중첩을 줄이는데 도움을 줍니다.

홀수를 출력해주는 예시는 아래처럼 생길 수도 있습니다.

for (let i = 0; i < 10; i++) {
    if(i % 2) alert(i);
}

이 예시는 위쪽 예시와 동일합니다.

그런데 이렇게 코드를 작성하면 부작용으로 중첩 레벨(중괄호 안의 alert 호출)이 하나 더 늘어납니다. if 안의 코드가 길어진다면 전체 가독성이 떨어질 수 있습니다.

'?' 오른쪽엔 break 나 continue 가 올 수 없습니다.

표현식이 아닌 문법 구조(syntax construct)는 삼항 연산자 ? 에 사용할 수 없다는 점을 항상 유의해야 합니다. 특히 breakcontinue 같은 지시자는 상항 연산자에 사용하면 안됩니다.

if (i < 5) alert(i);
else continue;

위 코드를 아래와 같이 바꾸게 되면 문법 에러를 발생 시킵니다.

(i > 5) ? alert(i) : continue; // 문법 에러

이는 물음표 연산자 ?if 문 대용으로 쓰지 말아야 하는 이유 중 하나입니다.

break/continue 와 레이블

여러 개의 중첩 반복문을 한 번에 빠져나와야 하는 경우가 종종 생기곤 합니다.

이때 레이블을 사용하면 됩니다. 레이블(label) 은 반복문 앞에 콜론과 함께 쓰이는 식별자입니다.

labelName: for (...) {
    for (...) {
        if (...) break labelName;
    }
}
alert('완료!'); // if 문에 해당되면 이중 for 문을 빠져나와 실행된다. 

switch문

복수의 if 조건문은 switch 문으로 바꿀 수 있습니다.

switch 문을 사용한 비교법은 특정 변수를 다양한 상황에서 비교할 수 있게 해줍니다. 코드 자체가 비교 상황을 잘 설명한다는 장점도 있습니다.

문법

switch 문은 하나 이상의 case 문으로 구성되며 대개 default 문도 있지만, 이는 필수는 아닙니다.

let a = 2 + 2;

switch(a) {
    case 3:
        alert( '비교하려는 값보다 작습니다.' );
        break;
    case 4:
        alert( '비교하려는 값과 일치합니다.' );
        break;
    case 5:
        alert( '비교하려는 값보다 큽니다.' );
        break;
    default:
        alert( "어떤 값인지 파악이 되지 않습니다." );
}

case 문 안에 break 문이 없으면 조건에 부합하는지 여부를 따지지 않고 이어지는 case 문을 실행합니다. 위 코드에서 break 문이 없는 경우 아래와 같이 출력됩니다.

비교하려는 값과 일치합니다.
비교하려는 값보다 큽니다.
어떤 값인지 파악이 되지 않습니다.

여러 개의 "case" 문 묶기

let a = 3;
switch(a) {
    case 4:
        alert('계산이 맞습니다!');
        break;
    case 3:
    case 5:
        alert('계산이 틀립니다!');
        break;
    default:
        alert('계산 결과가 이상하네요.');
}

위 코드에서 case 3case 5 는 동일한 메세지를 보여줍니다. swicth/case 문에서 break 문이 없는 경우엔 조건에 상관없이 다음 case 문이 실행되는 부작용이 발생합니다.

자료형의 중요성

비교하려는 값과case 문의 값의 형과 값이 같아야 해당 case 문이 실행됩니다.

let arg = prompt("값을 입력해주세요.:");
switch(arg) {
    case '0':
    case '1':
        alert( '0이나 1을 입력하셨습니다.' );
        break;
    case '2':
        alert( '2를 입력하셨습니다.' );
        break;
    case 3 :
        alert( '이 코드는 절대 실행되지 않습니다.' );
        break;
    default:
        alert( '알 수 없는 값을 입력하셨습니다.' );
    
}

위 코드에서 3 을 입력하였더라도 세 번째 alert 문은 실행되지 않습니다. prompt 함수는 사용자가 입력 필드에 기재한 값을 문자열로 변환해 반환하기 때문에 숫자 3 을 입력하더라도 prompt 함수는 문자열 '3' 을 반환합니다.

Last updated