자바스크립트 완벽 가이드/ 문장

표현문

자바스크립트 문장 중에서 가장 간단한 종류는 바로 부수 효과가 있는 표현식이다. 할당문이 표현문의 주요 부류

복합문

자바스크립트에서는 하나의 문장에 다수의 문장을 합칠 수 있는 방법을 제공한다.(문장 블록이라고도 한다) 문장이 몇 개이든 상관없이 그저 단순히 중괄호로 감싸면 된다. 따라서 다음의 코드는 단일 문장과 마찬가지로 작동하며, 자바스크립트에서 단일 문장을 받는 어디에서라도 사용할 수 있다.

{ 
    x = Math.PI;
    cx = Math.cos(x);
    alert("cos(" + x + ") =" +cx);
}

if

if 문은 자바스크립트가 무언가를 결정할 수 있는 조건부로 문장을 실행할 수 있는 기능을 제공하는 기본적인 제어문이다. if 문은 아래와 같은 형태로 사용된다.

if (표현식)
    문장

if (표현식)
    문장 1
else
    문장 2

else if

if 문을 중첩된 형태로 써도 되지만 else if 문을 사용하는 게 더 좋고 읽기도 편하다.

if ( n == 1) {
    // 코드 블럭 1 실행
}
else if ( n == 2) {
    // 코드 블럭 2 실행
}
else if ( n == 3) {
    // 코드 블럭 3 실행
}
else {
    // 모든 테스트가 false 이면 코드 블럭 4 실행
}

switch

if 문은 프로그램이 실행되는 흐름에 분기(branch)를 일으킨다. if 문을 여러개 사용해서 다중 분기를 수행할 수도 있지만 동일한 변수의 값을 반복해서 확인하는 것은 낭비가 되므로 이럴 때는 switch 문을 사용하는 것이 효율적이다.

switch 문이 실행되면 ‘표현식’의 값을 계산하고 이 값에 대응하는 case 레이블을 찾는다. 올바른 레이블을 찾으면 해당 case 레이블 직후에 나오는 코드 블록의 첫 번째 문장부터 실행하기 시작한다. 표현식의 값과 대응하는 case 레이블을 찾지 못하면, 이럴 때를 위한 특수 레이블인 default 레이블 직후의 첫 번째 문장부터 실행하기 시작한다. 만일 default 레이블도 없으면 모든 코드블록을 건너 뛴다.

switch(n) {
    case 1:
    // 코드 블록 1 실행 break;
    case 2:
    // 코드 블록 2 실행 break;
    case 3:
    // 코드 블록 3 실행 break;
    default:
    // 코드 블록 4 실행 break;
}

switch 문에 break 문이 없다면 switch 문은 그 ‘표현식’의 값에 대응하는 case 레이블의 코드 블록에서 실행을 시작하여 switch 문 블록의 끝까지 계속 실행한다. 간혹 유용할 때도 있긴 하지만 switch 문에서 모든 case의 끝마다 break 문을 삽입하는 것을 잊지 말아야 한다.(때로는 return 문도 사용할 수 있다)

while

while 무은 기본적인 반복문으로서 자바스크립트로 하여금 무언가 반복적인 행동을 수행할 수 있게 한다.

while (표현식)
    문장

while 문은 먼저 ‘표현식’을 평가하는 것으로 시작한다. 그 값이 false이면 자바스크립트는 프로그램의 다음 문장으로 진행한다. 그 값이 true이면 while 루프의 몸체를 형성하는 ‘문장’이 실행된 후, ‘표현식’이 다시 평가된다. 다시 평가된 ‘표현식’의 값이 false라면 자바스크립트는 프로그램의 다음 문장으로 진행하고 그렇지 않으면 ‘문장’을 다시 실행한다.

do/while

do/while 루프는 while 루프와 많은 점에서 비슷하지만 차이점이라면 루프 표현식이 테스트되는 곳이 루프의 처음이 아니라 마지막이기 때문에 언제나 적어도 한 번은 루프 몸체가 실행된다는 점이다.

do
    문장
while (표현식) ;

실제 코딩에서 최소 한 번 이상 루프를 실행해야 한다고 확신하는 경우가 흔치 않기 때문에, do/while 문은 while 만큼 자주 사용되는 편은 아니다.

for

대게 for 문을 사용하면 while 문보다 좀 더 편리하게 루프를 만들 수 있다. 초기화, 테스트, 갱신은 루프 변수에 대한 가장 핵심적인 세 가지 작업인데 for문은 이러한 세 단계를 루프 문법 내부에 명시적으로 못 박아 놓고 있기 때문에 for 루프의 작동을 이해하기가 더 간단하다.

for (초기화; 테스트; 증가)
    문장

for/in

for (변수 in 객체)
    문장

‘변수’는 변수 이름, 또는 변수/ 배열 객체/ 객체 프로퍼티를 선언하는 var문이어야 한다.(즉, 할당 표현식의 좌변에 적합한 표현식이어야 한다.) ‘객체’는 객체 이름 또는 객체로 평가될 수 있는 표현식이어야 한다.

배열의 모든 원소에 대해 루프를 돌리려면 간단히 인덱스 변수를 증가시키면서 while 문이나 for 문을 돌리면 된다. for/in 문은 객체의 모든 프로퍼티에 대해 루프를 돌리는 방법을 제공한다. –객체가 갖고 있는 프로퍼티의 개수를 알 수 없으므로 하는 방식인 듯. 배열은 인덱스 번호 때문에 하나씩 증가 시켜서 하면 되지만 객체는 그런게 없고, 또 객체의 프로퍼티 개수를 명확히 모르므로 사용하는 것 같다.– for/in 루프의 몸체는 ‘객체’의 각 프로퍼티 마다 한 번씩 실행되는데, 루프 몸체가 실행되기에 앞서 객체에 속한 프로퍼티들 중 하나의 이름이 ‘변수’에 문자열의 형태로 할당된다. 루프 몸체 속에서는 이 이름을 연산자 속에 사용하여 해당되는 객체 프로퍼티의 값을 찾을 수 있다. 예를 들어 다음 for/in 루프는 주어진 객체의 모든 프로퍼티에 대해 이름과 값을 출력한다.

for(var prop in my_object) {
    document.write("name: " + prop + "; value:" + my_object[prop], " ");
}

var 하고 쓰는 변수는 루프 문 내에서 사용하기 위한 이름을 쓰면 되고, 그것이 객체와 관련 있는 것은 아닌 듯. 내부적으로는 그 변수에 프로퍼티를 대입한 뒤에 결과를 알려주는 것 같다. 저 구문 자체가 모든 프로퍼티의 수 만큼 실행하라는 뜻을 갖고 있는 듯.

for/in 루프의 ‘변수’에는 임의의 표현식을 사용할 수 있다.(최소한 할당 표현식의 좌변에 적합한 무언가로 평가되기만 한다면) 이 표현식은 루프가 매회 돌 때마다 평가된다. 즉 매회 다르게 평가될 수 있다는 것을 의미한다. 예를 들어 다음과 같은 코드를 사용하면 주어진 객체의 모든 프로퍼티 이름을 배열에 복사할 수 있다.

var o = { x:1, y:2, z:3 };
var a = new Array( );
var i = 0;
for ( a[i++] in o ) // 이렇게 놓고 문장에 o의 객체를 a[i]에 대입한다고 쓰면 된다.

레이블

switch 문에서 쓰이는 case와 default 레이블은 특별한 레이블 문이다. 어떤 문장에라도 그 앞에 식별자 이름과 콜론을 삽입함으로써 레이블을 붙일 수 있다.

식별자: 문장

예약어를 제외한 모든 적법한 자바스크립트 식별자는 ‘식별자’가 될 수 있다. 레이블 이름은 변수나 함수 이름과는 전혀 별개로 취급되기 때문에 변수나 함수 이름과 충돌할 일은 없다.

parser:
while(token != null) {
    // 코드 생략
}

어떤 문장에 레이블을 붙이면 프로그램의 다른 곳에서 그 문장을 참조할 수 있는 이름이 생기는셈이다. 레이블은 어떤 문장에라도 붙일 수 있다.

break

break 문을 사용하면 break 문을 감싸고 있던 가장 안쪽의 루프나 switch 문에서 즉시 빠져 나온다. break의 역할은 switch에서 빠져 나오게 하는 것이므로, break; 와 같이 사용되는 방식은 오직 루프나 switch 문 내부에서만 적법한 것이 된다.

자바스크립트에서는 break 키워드 뒤에 레이블 이름이 따라올 수도 있다. 이때 레이블 이름에는 콜론(:) 없이 오직 식별자만 써야 한다.

break 레이블이름;

break가 레이블과 함께 쓰이면, 해다 레이블 이름이 붙은 문장의 끝으로 건너뛴다. 즉, 그 문장을 종료한다. 여기서 레이블이 붙은 문장이란, 어떤 형태로은 다른 문장들을 둘러싸고 있는 문장이다. 굳이 루프나 switch 문이 아니어도 상관없으며, 심지어 레이블과 함께 쓰인 break 문이 루프나 switch 문에 포함되지 않아도 상관없다. break 문에 쓰인 레이블의 유일한 조건은 문장들의 블록을 지칭하는 이름이어야 한다는 것이다. 이 레이블이 가리키는 것이 if 문일 수도 있고, 그저 중괄호로 둘러싸인 이름을 붙인 문장 블록일 수도 있다.

continue

continue 문은 break 문과 유사하지만 루프를 빠져 나오지 않고 새로운 반복을 시작하는 점이 다르다..

continue;

continue 문 역시 레이블과 함께 쓰일 수 있다.

continue 레이블이름;

continue 문은 단독 형식이든 레이블 형식이든 항상 while, do/while, for, for/in 루프 몸체 내부에서만 사용되어야 하고, 이외의 부분에 사용되면 문법 에러가 발생한다.

continue 문이 실행되면 이를 감싸고 있던 루프의 현재 반복을 종료하고 다음 반복을 시작한다. 이때 루프의 종류에 따라 각기 다른 일이 일어난다.

  • while 루프에서는 루프의 시작 부분에 지정된 ‘표현식’을 다시 테스트한다. 결과가 true 이면 루프 몸체 처음부터 다시 실행을 시작한다.
  • do/ while 루프에서는 일단 루프의 끝 부분까지 건너뛴다. 그리고 루프 조건을 다시 테스트하여 결과가 true이면 루프 몸체 처음부터 다시 실행을 시작한다.
  • for 루프에서는 ‘증가’ 표현식을 평가한 후 ‘테스트’ 표현식을 테스트하여 다음 반복을 수행할 지 여부를 판단한다.
  • for/ in 루프에서는 다음 ㅏ례의 프로퍼티 이름을 루프 시작에서 지정된 변수에 할당한 후 루프를 다시 시작한다.

var

var 문은 명시적으로 하나 또는 그 이상의 변수를 선언하는데 쓰인다. var 키워드 다음에 선언될 변수들은 쉼표로 구분되어 이어진다.

var 문에서 변수에 초기값을 지정하지 않으면 그 변수가 정의는 되지만 초기값은 undefined가 된다.

function

function 문은 자바스크립트 함수를 정의하는데 쓰인다. 문장은 실행 시간에 실행되는 반면, 함수는 자바스크립트 코드가 실제로 실행되기 이전의 파싱(parsing) 또는 컴파일 단계에서 정의된다. 자바스크립트 파서(parser)가 함수 정의를 만나면 이 함수의 몸체를 이루는 문장들을 파싱하고 저장한다(실행하지는 않는다.) 그러고 나서 이 함수를 유지할 프로퍼티를 이 함수와 동일한 이름으로 정의한다.(이 함수 정의가 다른 함수 안에 중첩되어 있다면 호출 객체에 프로퍼티를 정의하며, 그렇지 않다면 전역 객체에 정의한다)

return

return 문은 함수 호출 표현식의 값, 즉 함수에서 반환되는 값을 지정하는데 쓰인다. return 문은 오직 함수 몸체 내부에서만 나타날 수 있고, 다른 곳에서 나타나면 문법 에러가 일어난다.

함수에서 ‘표현식’이 없는 return 문을 실행하거나 함수 몸체의 끝에 도달하여 함수가 반환된다면, 해당 함수 호출 표현식의 값은 undefined가 된다.

throw

‘예외’란 무언가 예외적인 상황이나 에러가 발생했음을 가리키는 신호이다. 예외를 ‘발생시키다(throw)’라는 것은 그런 에러나 예외 상황을 알린다는 뜻이다. 한 편 예외를 ‘잡아내다(catch)’라는 것은 그것을 처리한다는 뜻이다.(즉, 그 예외에서 회복하기 위해 무언가 필요하거나 적절한 행동을 취한다는 뜻이다). 자바스크립트에서는 런타임 에러가 일어날 때마다 예외를 발생시킨다. 또한 프로그램에서 throw 문을 사용하여 명시적으로 예외를 발생시킬 때에도 마찬가지로 예외를 발생시킨다. 예외를 잡아내는 데에는 try/ catch/ finally 문을 사용한다.

throw 문의 문법은 다음과 같다.

throw 표현식;

‘표현식’의 결과값 타입은 무엇이든 될 수 있다. 하지만 대부분 그 타입은 Error 객체 또는 Error의 하위 클래스 중 하나의 인스턴스가 되곤 한다. 때로는 에러 메시지를 담고 있는 문자열이나 어떤 에러 코드를 나타내는 숫자 값도 유용할 수 있다. 다음의 샘플 코드에서 예외를 발생시키는데 throw 문이 어떻게 쓰이는지 살펴볼 수 있다.

function factorial(x) {

    // 만약 입력 전달인자가 유효하지 않으면 예외를 발생시킨다!
    if (x<0) throw new Error("x must not be negative");

    // 유효하다면 값을 계산하여 정상적으로 반환한다. 
    for (var f = 1; x > 1; f *= x, x--);

    return f;
}

예외가 발생하면 자바스크립트 인터프리터는 정상적인 프로그램 실행을 즉시 중단하고 가장 가까운 예외 처리기로 넘어간다. 예외 처리기는 try/ catch/ finally 중에서 catch 절을 사용하여 작성된다. 예외를 발생시켰던 코드 블록이 catch 절과 연결되어 있지 않으면, 인터프리터는 바로 상위 단계를 감싸고 있는 코드 블록에 예외 처리기가 연결되어 있는지 확인한다. 처리기를 찾을 때까지 이 과정이 반복된다. 만일 예외를 처리할 try/ catch/ finally 문이 없는 함수 안에서 예외가 발생했다면 해당 함수를 호출했던 블록으로 그 예외가 전파되어 올라간다. 이 같은 방법으로 자바스크립트의 언어적인 구조를 따라서, 즉 호출 스택(call stack)을 따라서 예외가 전파되어 올라간다. 그래도 아무런 예외 처리기도 찾을 수 없으면 이 예외는 에러로 취급되어 사용자에게 보고된다.

try/ catch/ finally

try/ catch/ finally 문은 자바스크립트의 예외 처리 기법이다. 이 문장에서 try 절은 그저 처리할 예외가 발생할지도 모를 코드 블록을 정의하는 역할을 한다. try 블록 다음에는 catch 절이 이어진다. catch 절은 try 블록 내부에서 예외가 발생할 경우 호출되는 문장 블록이다. catch 절 다음에는 finally 블록이 이어지는데, 여기에는 앞서 try 블록에서 일어난 일에 관계없이 항상 실행이 보장되어야 할 뒷저리용 코드가 포함된다. catch나 finally 블록은 생략할 수 있다. 하지만 try 블록은 catch나 finally 중 적어도 하나 이상의 블록과 함께 사용되어야만 한다.

try {
    // 사용자에게 입력을 요청
    var n = prompt("please enter a positive integer", "");    
    // 사용자의 입력이 유효하다고 가정하고 그 숫자의 계승(factorial)을 계산한다.

    var f = factorial(n);
    // 결과를 표시한다.

    alert(n +"! =" + f);
    }
catch(ex) { // 만일 사용자의 입력이 유효하지 않다면 이곳에 도달한다.
    // 사용자에게 에러가 무엇인지 알린다.
    alert(ex);
}

with

with 문은 유효 범위 체인을 임시로 변경하려 할 때 쓰인다.

with (객체)
    문장

위 문장은 유효 범위 체인의 첫머리에 ‘객체’를 추가한다. 그러고 나서 ‘문장’을 실행한 다음, 유효 범위 체인을 원래의 상태로 되돌려 놓는다.

실제 코딩에서 with 문을 사용하면 상당히 많은 양의 타이핑을 절약할 수 있다.

frames[1].document.forms[0].address.value

위의 폼을 여러 번 접근하려 할 때 with 문을 사용하면 아래와 같이 사용할 수 있다.

with(frame[1].document.forms[0]) {
    // 여기서는 폼 엘리먼트에 직접 접근할 수 있다.
    name.value = "";
    address.value = "";
    email.value = "";
}

with를 사용하는 자바스크립트 코드는 최적화 하기 어렵고, with 문을 사용하지 않고 작성된 동등한 코드에 비해 느리기 때문에 with 문은 가급적 사용하지 않는 편이 낫다. 타이핑을 아끼기 위해서라면 아래와 같은 방법이 좋다.

var form = frames[1].document.forms[0];
form.name.value = "";
form.address.value = "";
form.email.value = "";

빈 문장

빈 문장은 아래와 같이 생겼다. 빈 문장은 아무런 효과도 없지만 몸체가 없는 루프를 생성하려 할 때 이따금 유용하게 쓰인다.

// 배열 a 를 초기화한다.
for (i=0; i < a.length; a[i++] = 0) ;

try/ catch/ finally 블록은 모두 중괄호로 시작해서 중괄호로 끝나야 한다. 이는 필수로 요구되는 문법으로 설사 해당 절에 단 하나의 문장만 있다 하더라도 마찬가지다.

It's only fair to share...Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn

The author

지성을 추구하는 디자이너/ suyeongpark@abyne.com

댓글 남기기