Language/JavaScript [JavaScript] 함수
  • 728x90
    반응형

     

     

     

    함수의 정의

    자바스크립트에서 함수의 정의는 function 키워드로 시작되며, 다음과 같은 구성요소를 가진다.

    1. 함수의 이름
    2. 괄호 안에 쉼표(,)로 구분되는 함수의 매개변수(parameter)
    3. 중괄호({})로 둘러싸인 자바스크립트 실행문
    자바스크립트에서 함수를 정의하는 문법은 다음과 같다.

     

    문법

    function 함수 이름(매개변수1, 매개변수2, ...) {

        함수가 호출되었을 때 실행하고자 하는 실행문;

    }

     

    함수 이름(function name)은 함수를 구분하는 식별자(identifier)이다.

    매개변수(parameter)란 함수를 호출할 때 인수(argument)로 전달된 값을 함수 내부에서 사용할 수 있게 해주는 변수이다.

     

    💡 Tip ? 함수의 인수(argument)란 함수가 호출될 때 함수로 값을 전달해주는 변수나 상수를 의미한다.

     

     

     

    값으로서의 함수

    자바스크립트에서 함수는 문법적 구문일뿐만 아니라 값(value)이기도 하다.

    따라서 함수가 변수에 대입될 수도 있으며, 다른 함수의 인수로 전달될 수도 있다.

     

    다음 예제는 함수를 변수에 저장하여 사용하는 예제이다.

     

    🔔 예제)

    function sqr(x) {    // 제곱의 값을 구하는 함수 sqr를 정의함.
    	return x * x;
    }
    
    var sqrNum = sqr;    				      // 변수 sqrNum에 함수 sqr을 대입함.
    document.write(sqr(4) + "<br>");    // 함수 sqr을 호출함.
    document.write(sqrNum(4));    		      // 변수 sqrNum를 함수처럼 호출함.

     

     

     

    함수 호이스팅(hoisting)

    자바스크립트에서 함수의 유효 범위라는 것은 함수 안에서 선언된 모든 변수는 함수 전체에 걸쳐 유효하다는 의미이다.

     

    근데 이 유효 범위의 적용이 변수가 선언되기 전에도 똑같이 적용된다.

    이러한 자바스크립트의 특징을 함수 호이스팅(hoisting)이라고 한다. 즉, 자바스크립트 함수 안에 있는 모든 변수의 선언은 함수의 맨 처음으로 이동된 것처럼 동작한다.

     

    🔔 예제)

    <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <title>JavaScript Function Scope</title>
    </head>
    <body>
        <h1>함수 호이스팅</h1>
    
        <script>
            var globalNum = 10;        // globalNum을 전역 변수로 선언함.
    
            function printNum() {
                document.write("지역 변수 globalNum 선언 전의 globalNum의 값은 " + globalNum + "입니다.<br>");
                var globalNum = 20;    // globalNum을 지역 변수로 선언함.
                document.write("지역 변수 globalNum 선언 후의 globalNum의 값은 " + globalNum + "입니다.<br>");
            }
            printNum();
       </script>    
    </body>
    </html>

     

    실행 결과

     

    함수 호이스팅

     

    위의 예제에서 17라인 시점에서는 변수 globalNum가 전역 변수를 가리킨다고 생각하기 쉽다. 하지만 자바스크립트 내부에서는 함수 호이스팅에 의해 다음과 같이 코드가 변경되어 처리된다.

     

    💡 호이스팅 후의 코드

    var globalNum = 10;
    
    function printNum() {
    	var globalNum;    // 함수 호이스팅에 의해 변수의 선언 부분이 함수의 맨 처음 부분으로 이동됨.
    
    	document.write("지역 변수 globalNum 선언 전의 globalNum의 값은 " + globalNum + "입니다.<br>");
    
    	globalNum = 20;
    
    	document.write("지역 변수 globalNum 선언 후의 globalNum의 값은 " + globalNum + "입니다.<br>");
    }
    
    printNum();

     

    위의 예제 3번라인 시점에서는 globalNum라는 지역 변수가 선언만 되어 있고, 아직 초기화만 안 된 상태이다. 따라서 이때 globalNum 변수에 접근하면 아직 초기화되지 않은 변수에 접근했으므로, undefined 값을 반환하게 된다. 실제로 변수가 초기화되는 시점은 원래 코드에서 변수가 선언된 5번라인의 시점이다.

     

    💡 Tip ? 자바스크립트에서는 함수 호이스팅이 자동으로 수행되지만, 항상 함수 블록의 첫 부분에 변수를 선언하는 것이 좋다.

     

     

     

     

    매개변수(parameter)

    자바스크립트에서는 함수를 정의할 때는 매개변수의 타입을 따로 명시하지 않는다.

    함수를 호출할 때에도 인수(argument)로 전달된 값에 대해 어떠한 타입 검사도 하지 않는다.

     

    함수를 호출할 때 함수의 정의보다 적은 수의 인수가 전달되더라도, 다른 언어와는 달리 오류를 발생시키지 않는다. 이 같은 경우 자바스크립트는 전달되지 않은 나머지 매개변수에 자동으로 undefined 값을 설정한다.

     

    💡 Tip ? 매개변수(parameter)란 함수의 정의에서 전달받은 인수를 함수 내부로 전달하기 위해 사용하는 변수를 의미 한다. 인수(argument)란 함수가 호출될 때 함수로 값을 전달해주는 값을 의미한다.

     

    다음 예제는 3개의 매개변수를 가지는 함수에 각각 다른 수의 인수를 전달하는 예제이다.

     

    🔔 예제)

    function addNum(x, y, z) {    // x, y, z 라는 3개의 매개변수를 가지는 함수 addNum()을 정의함.
    	return x + y + z;
    }
    
    addNum(1, 2, 3);    // 인수로 1, 2, 3을 전달하여 함수를 호출함. -> 6
    addNum(1, 2);       // 인수로 1, 2을 전달하여 함수를 호출함. -> NaN
    addNum(1);          // 인수로 1을 전달하여 함수를 호출함. -> NaN
    addNum();          // 인수로 아무것도 전달하지 않고 함수를 호출함. -> NaN

     

    위의 예제에서 addNum() 함수를 호출할 때 인수가 세 개보다 적게 전달되면, 계산할 수 없다는 의미인 NaN을 반환한다.

    그 이유는 전달되지 않은 나머지 값이 자동으로 undefined 값으로 설정되어, 산술 연산을 수행할 수 없기 때문이다.

     

    하지만 다음 예제처럼 하면 NaN을 반환하지 않고 전달된 인수만을 가지고 정상적으로 계산하는 함수를 작성할 수 있다.

     

    🔔 예제)

    function addNum(x, y, z) {
    
        if(x === undefined)    	// 함수 호출시 x에 해당하는 인수가 전달되지 않은 경우
        	x = 0;    			// 변수 x의 값을 undefined에서 0으로 변경함.
            
        if(y === undefined)    	// 함수 호출시 y에 해당하는 인수가 전달되지 않은 경우
        	y = 0;    			// 변수 y의 값을 undefined에서 0으로 변경함.
    
        if(z === undefined)    	// 함수 호출시 z에 해당하는 인수가 전달되지 않은 경우
        	z = 0;    			// 변수 z의 값을 undefined 에서 0으로 변경함.
    
        return x + y + z;
    }
    
    addNum(1, 2, 3);    // 6
    addNum(1, 2);       // 3
    addNum(1);          // 1
    addNum();           // 0

     

     

     

     

    argument 객체

    만약 함수의 정의보다 더 많은 수의 인수가 전달되면, 매개변수에 대입되지 못한 인수들은 참조할 방법이 없게 된다.

    하지만 arguments 객체를 이용하면, 함수로 전달된 인수의 총 개수를 확인하거나, 각각의 인수에도 바로 접근할 수 있다.

     

    argument 객체는 함수가 호출될 때 전달된 인수를 배열의 형태로 저장하고 있다.

    첫 번째 인수는 arguments[0]에 저장되며, 다음 인수는 arguments[1]에 저장된다. 또한, 인수의 총 개수는 arguments 객체 length 프로퍼티에 저장 된다.

     

    다음 예제의 addNum() 함수는 전달받는 인수의 개수 상관없이 언제나 정상적인 계산을 수행한다.

     

    🔔 예제)

    <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <title>JavaScript Parameters and Arguments</title>
    </head>
    <body>
        <h1>arguments 객체</h1>
    
        <script>
            function addNum() {
                var sum = 0;    // 합을 저장할 변수 sum을 선언함.
                for(var i = 0; i < arguments.length; i++) {    // 전달받은 인수의 총 수만큼 반복함.
                    sum += arguments[i];                    // 각각의 인수를 sum에 더함.
                }
                return sum;
            }
            document.write("인수가 3개 전달되면 반환값은 " + addNum(1, 2, 3) + "입니다.<br>");
            document.write("인수가 2개 전달되면 반환값은 " + addNum(1, 2) + "입니다.<br>");
            document.write("인수가 1개 전달되면 반환값은 " + addNum(1) + "입니다.<br>");
            document.write("인수가 아무것도 전달되지 않으면 반환값은 " + addNum() + "입니다.<br>");
            document.write("인수가 10개나 전달되도 반환값은 " + addNum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + "로 잘 동작합니다!!");
       </script>    
    </body>
    </html>​

     

    실행 결과

     

    arguments 객체

     

     

     

    728x90
    반응형

    'Language > JavaScript' 카테고리의 다른 글

    [JavaScript] 프로토 타입  (0) 2018.10.17
    [JavaScript] 객체  (0) 2018.10.17
    [JavaScript] 배열의 기초  (0) 2018.10.16
    [JavaScript] 반복문(for/in, for/of)  (0) 2018.10.16
    [JavaScript] 기타 연산자  (0) 2018.10.15
상단으로