본문 바로가기
프로그래밍/예제로 배우는 자바스크립트 요약 및 분석(IT 전공 서적)

예제로 배우는 자바스크립트 요약 및 코드 분석 4장 4.1~4.2

by 리드민 2023. 10. 8.
반응형

4장 함수

  함수는 특정 기능을 수행하며, 한번 정의해 놓으면 언제든지 필요할 때 호출하여 재사용할 수 있다. 4장에서는 자바스크립트에서 사용되는 함수의 정의와 호출, 익명함수, 함수의 매개변수, 함수 값의 반환에 대해 배운다. 또한 함수의 이름이 없는 익명 함수와 유효한 변수 범위를 의미하는 스코프에 대해 익힌다. 마지막으로 전역 변수와 같은 방식으로 동작하지만 변수 값을 보호할 수 있는 클로저에 대해서도 학습한다.

 

4.1 함수란?

  컴퓨터 프로그래밍 언어에서 함수(function)은 어떤 역활을 수행하는 것이라고 생각하면 된다. 우리가 그동안 사용해온 document.write(), alert() 등도 일종의 함수이다. document.write()의 역활은 브라우저 화면에 데이터를 출력하는 것이고, alert() 함수는 알림창에 메시지를 출력하는 역활을 담당한다.

  함수를 사용하는 가장 큰 이유는 재사용이 가능하다는 것이다. 한번 정의해 놓으면 언제든지 필요할 때마다 호출해서 사용할 수 있다. alert() 함수와 같이 자바스크립트 내부에 정의되어 있는 함수를 내장 함수(built-in function)이라고 한다. 그리고 내장 함수 외에는 사용자게 직접 함사룰 정의하여 사용해야 한다. 이런 함수를 사용자 함수(user-defined function)이라고 부른다.

 

4.1.1 함수 정의와 호출

  다음 코드를 통해서 사용자 함수를 정의하고 호출하는 방법에 대해서 알아보자.

예제 4-1. 사용자 함수 정의와 호출 hello_func.html 코드 원문
<script>
    function hello() {
            document.write("안녕하세요.<br>");
    }

    hello();
    hello();
    hello();
</script>
예제 4-1. 사용자 함수 정의와 호출 hello_func.html 코드 원문
<script>
	
    // 함수 hello() 선언부 시작
    function hello() {
    // hello()란 이름의 사용자 함수 선언
            document.write("안녕하세요.<br>");
            // 안녕하세요 출력하고 개행
    }
    // 함수 hello() 선언부 종료

    hello();
    // 함수 hello() 호출
    hello();
    // 함수 hello() 호출
    hello();
    // 함수 hello() 호출
</script>

 

4.1.2 매개변수와 함수 값 반환

  함수 정의에서는 매개변수(parameter)를 통해서 함수 호출 측에서 사용되는 변수나 데이터 값을 전달 받는다. 반대로 정의 함수에서 얻어진 결과값을 함수 호출 측에 반환(return) 할 수 있다.

 

다음 코드를 통해서 함수의 매개변수와 함수 반환 값에 대해서 알아보자.

예제 4-2. 함수의 매개변수와 반환 값 사용 예 circle_area_func.html 코드 원문
<p id="show"></p>
<script>
    function circleArea(r) {
        let result = r*r*3.14;
        return result;
    }

    let radius = 8;     // radius : 반지름
    let area;

    area = circleArea(radius);
    document.getElementById("show").innerHTML = "원의 넓이: " + area;
</script>
예제 4-2. 함수의 매개변수와 반환 값 사용 예 circle_area_func.html 코드 원문
<p id="show"></p>
// p 태그에 id show를 지정한다.
<script>
    function circleArea(r) {
    // 함수 circleArea(r)을 선언한다.
        let result = r*r*3.14;
        // 함수 result를 선언하고 r*r*3.14 연산의 결과값을 저장한다.
        return result;
        // 함수 result에 저장된 값을 리턴한다.
    }

    let radius = 8;     // radius : 반지름
    let area;
    // 변수 area를 선언한다.

    area = circleArea(radius);
    /* 사용자 정의 함수 circleArea() 함수를 호출하고 매개변수 r에
    변수 radius 값을 저장한 후 리턴값을 변수 area에 저장한다. */
    document.getElementById("show").innerHTML = "원의 넓이: " + area;
    /* document.getElementById 메서드를 이용해서 id의 'show'가 가리키는 요소
    단락 <p>를 불려온다. 그리고 innerHTML를 이옹해서 '"원의 넓이: " + area'
    를 출력한다.*/
</script>

<script> </script>로 표시된 자바스크립트 영역에서 프로그램은 메인 루틴(main routine)인 2부터 시작된다. let radius = 8; 부터다. 함수 정의 부분은 메인 루틴이 아니다.

 

4.1.3 함수로 섭씨/화씨 변환하기

  3장에서 섭씨를 화씨로 변환하는 프로그램에 대해서 공부했다. 이 프로그램을 함수를 이용해서 다시 작성해보면 다음과 같다.

예제 4-3. 함수를 이용한 섭씨/화씨 변환 c2f_func.html 코드 원문
<p id="show"></p>
<script>
    function c2f(a) {
        let b = (a * 1.8) +32;
        return b;
    }

    let c, f;   // c: 섭씨, f: 화씨
    let text ="";
    text += "---------------------<br>"
    text += "섭씨 화씨<br>"
    text += "---------------------<br>"
    for(let c=-10;c<=40; c+=10) {
        text += c + " " + c2f(c) + "<br>";      // c: 섭씨
    }

    document.getElementById("show").innerHTML = text;
</script>
예제 4-3. 함수를 이용한 섭씨/화씨 변환 c2f_func.html 코드 원문
<p id="show"></p>
// <p> 태그 선언하고 id값은 show로 한다.

// 자바스크립트 코드 시작
<script>
    function c2f(a) {
    // 사용자 함수 c2f(a)를 선언한다 매개변수는 a로 한다.
        let b = (a * 1.8) +32;
        // (a * 1.8) +32 연산의 결과값을 변수 b에 저장한다.
        return b;
        // 변수 b에 저장된 값을 반환값으로 한다.
    }

    let c, f;   // c: 섭씨, f: 화씨
    let text ="";
    // 문자열 변수 text를 선언하고 값을 null로 한다.
    text += "---------------------<br>"
    text += "섭씨 화씨<br>"
    text += "---------------------<br>"
    for(let c=-10;c<=40; c+=10) {
    // for문 선언, c가 -10~40까지 반복한다 증감값은 10씩 증가한다.
        text += c + " " + c2f(c) + "<br>";      // c: 섭씨
    }

    document.getElementById("show").innerHTML = text;
    /* document.getElementById() 메서드를 이용해서 id 'show'가 가리키는 요소
    단락 <p>를 불려온다. 그리고 innerHTML를 이용해서 text에 저장된 내용을 출력한다.
    for문에서 반복되는 내용이 출력된다. 내용은 섭씨 온도별 화씨 온도이다.*/
</script>

 

이번에는 앞 예제 4-3을 그림 4-4에서와 같이 <table> 태그를 이용해서 표로 만드는 방법에 대해서 알아보자.

예제 4-4. 예제 4-3의 결과를 표(<table> 태그)로 만들기 c2f_func2.html 코드 원문
<p id="show"></p>
<script>
    function c2f(a){
        let b = (a * 1.8) +32;
        return a;
    }

    let c, f;
    let text = "";
    text += "<table border='1'>";
    text += "<tr><td>섭씨</td><td>화씨</td></tr>"

    for (let c=-10; c<=40; c+=10) {
        f = c2f(c);
        text += "<tr><td>" + c + "</td><td>" + f + "</td></tr>";
    }
    text += "</table>";

    document.getElementById("show").innerHTML = text;
</script>
예제 4-4. 예제 4-3의 결과를 표(<table> 태그)로 만들기 c2f_func2.html 코드 원문
<p id="show"></p>
// html <p>태그 선언하고 id값을 "show"로 한다.
<script>
    function c2f(a){
    // 사용자 함수 c2f(a) 선언
        let b = (a * 1.8) +32;
        return a;
        // 반환값을 a로 한다.
    }

    let c, f;
    let text = "";
    text += "<table border='1'>";
    /* 변수 text에 문자열 "<table border='1'>"를 넣는다.
    html 테이블 선언 태그 이므로 테이블 선언이 된다.*/
    text += "<tr><td>섭씨</td><td>화씨</td></tr>"
    // 변수 text에 문자열 "<tr><td>섭씨</td><td>화씨</td></tr>를 넣는다.

    for (let c=-10; c<=40; c+=10) {
    // for문 선언 변수 let이 -10~40 동안 반복된다. 증감식은 c +-10이다.
        f = c2f(c);
        // 함수 c2f(c)를 매개변수 c로 호출하고 반환값을 변수 f에 저장한다.
        text += "<tr><td>" + c + "</td><td>" + f + "</td></tr>";
        // 변수 text에 문자열 "<tr><td>" + c + "</td><td> + f + "</td></tr>"을 저장한다.
    }
    text += "</table>";
    // 변수 text에 문자열 </table>를 저장한다.

    document.getElementById("show").innerHTML = text;
    /* 메서드 document.getElementById를 사용해서 id 'show'가 가리키는 요소 단락
    <p>를 불려온다. 그리고 innerHTML를 이용해서 text에 저장된 내용을 출력한다.
    섭씨 온도별 화씨 온도 표가 출력된다.*/
</script>

예제 4-3 프로그램에 <table>, <tr>, <td> 태그를 사용해서 테이블로 만들어서 출력해 보았다. 확인해보면 사용자 정의 함수인 'function c2f(a)'가 같은 것을 확인할 수 있다.

 

4.2 익명 함수

4.2.1 익명 함수란?

  익명 함수는 말 그대로 함수 이름이 없는 함수를 의미한다. 프로그래밍 하다보면 미리 함수 이름을 정하지 않고 필요할 때 함수를 만들어 사용하고 싶은 경우가 생긴다. 이 때 사용하는 함수가 익명 함수이다.

예제 4-5. 익명 함수 사용 예 anony_func.html 코드 원문
<p id="show"></p>
<script>
    const mul = function(a, b) { return a*b};

    let x = mul(5,8);
    document.getElementById("show").innerHTML = x;
</script>
예제 4-5. 익명 함수 사용 예 anony_func.html 코드 원문
<p id="show"></p>
// html 태그 p에 id show를 저장
<script>
    const mul = function(a, b) { return a*b};
    // 익명함수 function()를 선언하고 그 값을 상수 변수 mul에 저장

    let x = mul(5,8);
    // 익명함수를 가리키는 변수에 매개변수 5,8을 넣은 값을 변수 x에 저장
    document.getElementById("show").innerHTML = x;
    /* document.getElementById() 함수를 이용해서 id show 가 가리키는 요소
    단락 p를 불려온다. innerHTML를 사용해서 변수 x의 값을 출력한다. */
</script>

 

익명 함수는 변수를 선언하는 것과 같기 때문에 익명 함수에 의해 생성되는 함수의 이름을 쉽게 변경할 수 있다. 다음은 익명 함수를 저장한 변수에 다른 변수를 할당하여 익명 함수를 호출하는 예이다.

예제 4-6. 익명 함수 저장 변수를 다른 변수에 대입 anon_func2.html 코드 원문
<p id="show"></p>
<script>
    const mul = function(a, b) {return a*b };

    const mul2 = mul;
    let x = mul2(3,4);

    document.getElementById("show").innerHTML = x;
</script>
예제 4-6. 익명 함수 저장 변수를 다른 변수에 대입 anon_func2.html 코드 분석
<p id="show"></p>
// 태그 p를 선언하고 id에 show값을 지정한다.
<script>
    const mul = function(a, b) {return a*b };
    // 익명함수 선언후 변수 mul에 저장 변수 mul이 익명 함수를 저장하게 된다.

    const mul2 = mul;
    // 변수 mul2에 익명 함수를 저장하고 있는 mul을 할당
    let x = mul2(3,4);
    // 함수 mul2(3,4)의 결과값을 변수 x에 저장

    document.getElementById("show").innerHTML = x;
    // document.getElementById 메서드를 이용해서 id가 show인 곳을 지정하고
    innerHTML 함수를 이용해서 그 곳에 변수 x에 저장된 값을 출력
</script>
예제 4-6. 익명 함수 저장 변수를 다른 변수에 대입 anon_func2.html 코드 분석
<p id="show"></p>
// 태그 p를 선언하고 id에 show값을 지정한다.
<script>
    const mul = function(a, b) {return a*b };
    // 익명함수 선언후 변수 mul에 저장 변수 mul이 익명 함수를 저장하게 된다.

    const mul2 = mul;
    // 변수 mul2에 익명 함수를 저장하고 있는 mul을 할당
    let x = mul2(3,4);
    // 함수 mul2(3,4)의 결과값을 변수 x에 저장

    document.getElementById("show").innerHTML = x;
    // document.getElementById 메서드를 이용해서 id가 show인 곳을 지정하고
    innerHTML 함수를 이용해서 그 곳에 변수 x에 저장된 값을 출력
</script>

 

4.2.2 자기호출 익명 함수

  익명 함수에서는 일반적으로 함수의 기능을 정의하여 변수에 저장된 다음 호출해서 사용한다. 그러나 자기호출 익명 함수(self-invoking anonymous function)는 함수 정의와  호출이 동시에 일어나 바로 실행이 되는 함수이다.

 

자기호출 익명 함수는 다음과 같이 익명 함수를 괄호로 감싼 형태로 사용된다.

(function() {
     ...
})();

다음 예제를 통해서 자기호출 익명 함수의 사용법에 대해 알아보자.

예제 4-7. 자기호출 익명 함수 사용 예 self_invoking.html 코드 원문
<p id="show"></p>
<script>
    ( function() {
        document.getElementById("show").innerHTML = "안녕하세요!";
    }) ();
</script>
예제 4-7. 자기호출 익명 함수 사용 예 self_invoking.html 코드 분석
<p id="show"></p>
// html 태그 <p>를 선언하고 id에 show값을 지정
<script>
    ( function() {
    // 자기 호출 익명 함수 선언, 함수가 자기 자신을 호출해서 바로 실행
        document.getElementById("show").innerHTML = "안녕하세요!";
    }) ();
</script>

 

4.2.3 화살표 함수

  화살표 함수(arrow function)는 익명 함수를 축약해서 표현하는 형태이다. 화살표 함수에서는 익명 함수에서 사용되는 키워드 function, return, 중괄호({}) 대신 화살표(=>) 기호를 사용한다.

예제 4-8. 화살표 함수 사용 예 arrow_func.html
<p id="show"></p>
<script>
    const z = (x,y) => x+y;
    // const z = (x,y) => {return x+y};
    document.getElementById("show").innerHTML = z(10,20);
</script>
예제 4-8. 화살표 함수 사용 예 arrow_func.html
<p id="show"></p>
// 태그 p에 id값 show를 지정해서 선언
<script>
    const z = (x,y) => x+y;
    // 익명 함수를 화살표 함수로 표현, function, return, 중괄호({})를 다 생략했다.
    // const z = (x,y) => {return x+y};
    // 익명 함수를 화살표 함수로 표현, function, 중괄호({})를 생략했다.
    document.getElementById("show").innerHTML = z(10,20);
    /* document.getElementById("show") 함수를 이용해서 id가 show를 가지는 단락
    p로 이동한다. innerHTML를 이용해서 함수 z(10,20)를 출력한다. */
</script>

 

4.2.4 호이스팅

  자바스크립트는 기본적으로 변수나 함수 정의부를 프로그램 제일 앞으로 끌어 올린다. 이를 호이스팅이라고 한다. 호이스팅의 뜻은 '끌어 올리기'이다.

 

  다음 프로그램에서는 함수 호출이 함수 정의보다 먼저 일어나고 있다.  C, 자바, 파이썬 등의 프로그래밍 언어에서 이런 식의 프로그램은 오류를 발생시킨다. 함수 호출 이전에 반드시 함수 정의가 이루어져야 한다. 그러나 자바 스크립트에서는 호이스팅 기능으로 인해서 다음과 같은 프로그램이 정상적으로 작동한다.

예제 4-9. 함수 호출이 함수 정의보다 먼자 일어남 hoisting.html 코드 원문
<p id="show"></p>
<script>
    let x;
    x = mulFunc(10,20);     // 함수 호출
    document.getElementById("show").innerHTML = x;

    function mulFunc(a, b) {    // 함수 정의
        return a*b;
    }

</script>
예제 4-9. 함수 호출이 함수 정의보다 먼자 일어남 hoisting.html 코드 분석
<p id="show"></p>
// 태그 p를 선언하고 id값으로 show를 지정
<script>
    let x;
    x = mulFunc(10,20);     // 함수 호출
    document.getElementById("show").innerHTML = x;

    function mulFunc(a, b) {    // 함수 정의
        return a*b;
    }
    /* 함수 정의부가 뒤에 있어도 오류가 나지 않는다. 자동을 위로 끌어올려주기 때문이다.
	c, 자바, 파이썬 등의 프로그램에서는 함수 정의부가 뒤에 있으면 오류가 난다.*/
</script>

  그러나 익명 함수의 경우는 일반적인 함수와는 달리 함수를 정의해서 변수를 저장해서 사용하는 형태이므로 반드시 함수 호출 이전에 익명 함수를 선언해서 사용해야 한다.

  다음과 같이 익명함수를 호출할 다음 익명함수를 선언하면 오류가 발생한다.

예제 4-10. 익명 함수에서는 호이스팅이 적용되지 않음 hoisting2.html 코드 원문
<p id="show"></p>
<script>
	let x;
    x = mulFunc(10,20);		// 함수 호출
    document.getElementById("show").innerHTML = x;
    
    const mulFunc = function(a,b) {		// 익명 함수 정의
    	return a*b;
    }
</script>
예제 4-10. 익명 함수에서는 호이스팅이 적용되지 않음 hoisting2.html 코드 원문
<p id="show"></p>
<script>
	let x;
    x = mulFunc(10,20);		// 함수 호출
    // 익명함수이므로 함수 호출보다 익명 함수 정의가 더 먼저 이루어져야 한다.
    // 그러므로 오류가 난다.
    document.getElementById("show").innerHTML = x;
    
    const mulFunc = function(a,b) {		// 익명 함수 정의
    	return a*b;
    }
</script>

  자바 스크립트의 호이스팅 기능은 이론적으로 복잡하다. 오류가 날 수 있다. 그래서 코드를 작성할 때는 가급적 함수 정의를 먼저해주고 그 함수를 호출해서 사용하는 것이 좋다.

반응형