본문

함수(JavaScript)

반응형

# 함수


# 함수의 정의

- 어떤 입력 값을 이용해 미리 정의된 로직을 처리하여 결과를 반환하도록 만든, 여러번에 걸쳐 호출에 의해 실행될 수 있는 코드 블록

- 함수는 매개변수(parameter) 혹은 전달인자(argument)라고 불리는 지역변수를 가질 수 있는데, 이 매개변수는 함수를 호출하는 시점에 값을 갖게 됨

- 함수는 반환값을 가질 수 있는데, 반환값은 return문에 의해 함수를 호출한 표현식의 결과로 전달됨

 


# 함수를 정의하는 3가지 방법

1. function문을 이용해 함수를 정의

1
2
3
4
function 함수명([매개변수 목록]) {
문장들
[return 반환값;]
}
cs


2. 함수 리터럴을 이용해 함수를 정의 (이름없는 함수로 생성 및 초기화하여 변수에 대입해야한다)

1
2
3
4
var 변수명 = function([매개변수 목록]){
문장들
[return 반환값;]
};
cs


3. Function 생성자를 이용해 함수를 정의

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
var 변수명 = new Function(['매개변수' [, '매개변수'[,...]]]);
var 변수명 = new FUnction('[매개변수 목록]''문장들');
 
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="utf-8" />
    <title>04-01</title>
  </head>
  <body>
    <script type="text/javascript">
      // 함수의 정의와 호출
      
      // function 문에 의해 정의된 print 함수는 매개변수 message에 전달된 값을 출력합니다.
      function print(message) {
        document.writeln(message);
      }
      
      // function 문에 의해 정의된 println 함수는 매개변수 message에 전달된 값과 
      // 문자열 '<br/>'을 접합연산한 결과를 출력합니다. 
      function println(message) {
        document.writeln(message + '<br/>');
      }
      
      // function 문에 의해 정의된 distance 함수는 x, y 프로퍼티를 가진 객체를 매개변수로 하여 
      // 내장객체 Math가 제공하는 sqrt함수를 호출해 두 점간의 거리를 반환합니다.
      function distance(p1, p2) {
        var dX = p2.x - p1.x;
        var dY = p2.y - p1.y;
        return Math.sqrt(dX * dX, dY * dY); // 내장객체 Math가 제공하는 sqrt함수를 호출합니다.
      }
      
      var pointA = { x : 25, y : 40 };
      var pointB = { x : 50, y : 80 };
      
      print('pointA와 pointB 사이의 거리: ');
      println(distance(pointA, pointB));
      
      // 함수리터럴에 의해 정의된 area 함수는 x, y 프로퍼티를 가진 객체를 매개변수로 하여 
      // 두 점을 이용해 구성된 사각형의 면적을 반환합니다.
      var square = function(leftTop, rightButtom) {
        var width = rightButtom.x - leftTop.x;
        var height = rightButtom.y - leftTop.y;
        return width * height;
      };
      
      print('pointA와 pointB로 구성한 사각형의 넓이: ');
      println(square(pointA, pointB));
      
      // Function 생성자에 의해 정의된 triangle 함수는 base와 height 매개변수에 전달된 값을 이용해 
      // 삼각형의 면적을 반환합니다.
      var triangle = new Function('base''height''return (base * height) / 2;');
      print('base와 height로 구성한 삼각형의 넓이: ');
      println(triangle(3020));
    </script>
  </body>
</html>
cs


# 변수의 전역스코프와 지역스코프

- 스코프(scope)란 코드에서 변수를 참조할 수 있는 해당 변수의 유효범위를 결정하는 개념

- 자바스크립트는 코드 전체에서 접근 가능한 전역(global) 스코프와 함수 내의 코드에서만 접근 가능한 지역(local) 스코프만 존재

- 전역 스코프를 가진 변수를 전역 변수, 지역 스코프를 가진 변수를 지역 변수라고 함

자바스크립트는 블록({}) 스코프가 존재하지 않음에 유의


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="utf-8" />
    <title>04-02</title>
  </head>
  <body>
    <script type="text/javascript">
      // 전역 스코프와 지역 스코프
      
      // 전역 스코프를 가진 전역 변수    // 함수 외부 선언
      var x = 'global x';   
      var y = 'global y'
 
      
      function func() {
        
        // 지역 스코프를 가진 지역 변수는 반드시 var 키워드와 함께 선언되어야 합니다.
        var x = 'local x';
        
        // var 키워드 없을 경우 전역스코프에 접근해 동일 이름을 가진 전역변수를 사용하며,
        // 만일 동일 이름의 전역 변수가 없을 경우 전역변수를 새로 등록합니다.
        y = '???';    //var 키워드를 사용하지 않으면 전역변수로 된다.
        
        document.writeln('x: ' + x + '<br/>');
        document.writeln('y: ' + y + '<br/>'); 
        document.writeln('<br/>'); 
      }
      
      document.writeln('func() 호출 전<br/>');
      document.writeln('x: ' + x + '<br/>');
      document.writeln('y: ' + y + '<br/>');
      document.writeln('<br/>');
      
      document.writeln('func() 호출<br/>');
      func();
      
      document.writeln('func() 호출 후<br/>');
      document.writeln('x: ' + x + '<br/>');
      document.writeln('y: ' + y + '<br/>');   
      document.writeln('<br/>');
    </script>
  </body>
</html>
cs


# 함수의 매개변수와 스코프

- 함수의 매개변수는 지역스코프를 갖는 지역변수로, 함수를 호출하느느 표현식으로부터 그 값을 전달 받음

- 전역스코프의 전역변수 값을 함수의 매개변수로 전달할 때 그 값이 함수의 지역스코의 매개변수로 복사됨

- 이 전달된 값이 기본형일 경우 전역변수와 매개변수는 상호 독립적인 값이 되며, 참고값이 전달된 경우 전역변수와 매개변수가 동일 객체를 참조하게 됨


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="utf-8" />
    <title>04-03</title>
  </head>
  <body>
    <script type="text/javascript">
      // 함수의 매개변수와 스코프
      
      // 값을 매개변수로 전달하는 경우 함수 내에서의 매개변수 조작은 원본 값에 아무런 영향을 미치지 않습니다.
      function swapByValue (x, y) {
        var temp = x;
        x = y;
        y = temp;      
      }
      
      // 참조값을 매개변수로 전달하는 경우 매개변수가 원본 객체를 참조하므로 
      // 함수 내에서 매개변수를 통한 객체 조작은 원본 객체에 영향을 미칩니다. 
      function swapByReference (o) {
        var temp = o.x;
        o.x = o.y;
        o.y = temp;    
      }
      
      var a = 5;
      var b = 8;
      var obj = { x : 5, y : 8};    // 객체    : 매개변수로 객체를 넘기게되면 원본에 변경을 가할 수 있다.
      
      document.writeln('swap 함수 호출 전<br/>');
      document.writeln('a: ' + a + ', b: ' + b + '<br/>');
      document.writeln('obj.x: ' + obj.x + ', obj.y: ' + obj.y + '<br/>');
      document.writeln('<br/>');
      
      swapByValue(a, b);
      swapByReference(obj);
      
      document.writeln('swap 함수 호출 후<br/>');
      document.writeln('a: ' + a + ', b: ' + b + '<br/>');
      document.writeln('obj.x: ' + obj.x + ', obj.y: ' + obj.y + '<br/>');
      document.writeln('<br/>');
    </script>
  </body>
</html>
cs


# 함수의 매개변수와 인자

- 자바스크립트 함수는 함수 정의 시 선언된 매개변수에 상관없이 인자를 전달할 수 있으며,  어떤 데이터 타입의 값이라도 전달할 수 있음

- 선언된 매개변수보다 적은 수의 인자 값들을 전달하면, 값을 전달받지 못한 남은 매개변수들은 undefined 값을 갖게 됨

- 생략이 가능한 매개변수는 매개변수 목록의 끝에 위치하도록 하여 임의로 생략할 수 있게 만드는 것이 중요


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="utf-8" />
    <title>04-04</title>
  </head>
  <body>
    <script type="text/javascript">
      // 함수의 생략 가능한 매개변수
      
      function sum(array, start, end) {
        // 매개변수 array에 전달된 값이 없을 경우 빈 배열을 할당합니다.
        // if 문을 대신해 다음의 || 연산자를 이용한 조건문을 작성할 수도 있습니다.
        // array = array || [];
        if (!array) 
          array = [];
        // 매개변수 start에 전달된 값이 없을 경우 0을 할당합니다.  
        if (!start) start = 0;
        // 매개변수 end에 전달된 값이 없을 경우 배열의 원소의 갯수를 할당합니다.
        if (!end) end = array.length;
            
        // 매개변수 array에 전달된 값이  배열 객체일 경우에만 합계를 계산합니다.  
        if (array instanceof Array) {
          // 매개변수 start와 end에 전달된 값이 숫자일 경우에만 합계를 계산합니다.
          if ((typeof start) != 'number' || (typeof end) != 'number')
            throw new Error('sum(): 두번째 매개변수와 세번째 매개변수의 전달 인자는 숫자여야 합니다.');
       
          var result = 0;
          for (var i = start; i < end-1; i++) {
            // 배열 array의 원소가 숫자 타입일 경우에만 합계를 계산합니다.
            if ((typeof array[i]) != 'number')
              throw new Error('sum(): array[' + i + ']에 저장된 값  ' + array[i] + '는 숫자 타입이 아닙니다.'); 
            result += array[i];
          }
        
          return result;
          
        } else {  // 매개변수 array에 전달된 값이  배열 객체가 아닐 경우 예외를 발생시킵니다.
          throw new Error('sum(): 첫번째 매개변수의 전달 인자는 배열이어야 합니다.');
        }
      }
      
      var arr1 = [1,2,3,4,5];
      var obj = { name : '홍길동', phone : '010-1234-5678' };
      var arr2 = [1,2,'3rd',4,5];
      
      try {
        document.writeln('sum(arr1, 0, arr1.length): ' + sum(arr1, 0, arr1.length+ '<br/>');
        document.writeln('sum(arr1, 0, 4): ' + sum(arr1, 04+ '<br/>');
        document.writeln('sum(arr1, 0): ' + sum(arr1, 0+ '<br/>');
        document.writeln('sum(arr1, 2): ' + sum(arr1, 2+ '<br/>');
        document.writeln('sum(arr1): ' + sum(arr1) + '<br/>');
        document.writeln('sum(): ' + sum() + '<br/>');
        document.writeln('sum(obj): ' + sum(obj) + '<br/>');
      } catch (e) {
        document.writeln(e + '<br/>');
      }
      
      try {
        document.writeln('sum(arr1, \'x\', 4): ' + sum(arr1, 'x'4+ '<br/>');
      } catch (e) {
        document.writeln(e + '<br/>');          
      }
      
      try {
        document.writeln('sum(arr2): ' + sum(arr2) + '<br/>');
      } catch (e) {
        document.writeln(e + '<br/>');          
      }
      
      document.writeln('<br/>');
    </script>
  </body>
</html>
cs


# 함수와 명시적인 이름을 가진 인자 전달

- 함수 호출 시 매개변수를 객체로 전달하여, 메소드 내에서 전달된 객체의 프로퍼티를 인자로 활용하는 방법

- 코드의 가독성을 더욱 높일 수 있으며, 매개변수의 순서에 상관없이 값을 자유롭게 전달할 수 있고, 생략된 매개변수를 명확히 표현할 수 있는 특징이 있음


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="utf-8" />
    <title>04-05</title>
  </head>
  <body>
    <script type="text/javascript">
      // 함수와 명시적인 이름을 가진 인자 전달
    
      function power(arg) {
        // 매개변수 arg로 전달된 객체에 base프로퍼티가 정의되어 있지 않을 때 
        // base프로퍼티를 추가하며 1로 설정합니다. 
        if (!arg.base) {
          arg.base = 1;
        }
        
        // 매개변수 arg로 전달된 객체에 exponent프로퍼티가 정의되어 있지 않을 때 
        // exponent프로퍼티를 추가하며 0으로 설정합니다.
        if (!arg.exponent) {
          arg.exponent = 0;
        }
        
        // 내장객체 Math의 pow 함수를 호출해 결과를 반환합니다.
        return Math.pow(arg.base, arg.exponent);
      }
      
      document.writeln('power({base:3, exponent:2})의 결과 값: ' + power({base:3, exponent:2}) + '<br/>');
      document.writeln('power({base:3})의 결과 값: ' + power({base:3}) + '<br/>');
      document.writeln('power({exponent:2})의 결과 값: ' + power({exponent:2}) + '<br/>');
      document.writeln('<br/>');
    </script>
  </body>
</html>
cs



# 함수에 인자로 함수를 전달

- 자바스크립트에서 함수는 데이터의 속성을 갖고 있어서, 변수, 객체의 프로퍼티에도 저장될 수 있으며, 함수의 전달 인자로도 사용될 수 있음


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="utf-8" />
    <title>04-06</title>
  </head>
  <body>
    <script type="text/javascript">
 
      // 사칙연산 관련 메소드를 가진 calculator객체를 정의합니다.
      var calculator = {
        add : function(x, y) {
          return x + y;
        },
        subtract : function(x, y) {
          return x - y;
        },
        multiply : function(x, y) {
          return x * y;
        },
        divide : function(x, y) {
          return x / y;
        }
      };
      
      // 위에 정의된 calculator 객체의  메소드를 첫번째 매개변수의 전달 값으로, 
      // 나머지 두 개의 매개변수는 첫번째 매개변수로 전달된 calculator 객체의 메소드의 
      // 매개변수로 사용할 operate1 함수를 정의합니다.
      function operate1(operator, operand1, operand2) {
        return operator(operand1, operand2);
      }
      
      // 첫번째 매개변수로 calculator 객체의 프로퍼티명을 전달하고, 나머지 두 개의 매개변수는 
      // calculator 객체의 메소드의 매개변수로 사용할 operate2 함수를 정의합니다.
      function operate2(operatorName, operand1, operand2) {
        // 프로퍼티 타입이 함수일 경우 그 메소드를 실행합니다.
        if ((typeof calculator[operatorName]) == 'function')
          return calculator[operatorName](operand1, operand2);
        else
          throw new Error('operator2(): ' + operatorName + '은(는) 정의되어 있지 않은 연산자입니다.');   
      }
      
      // ((3 - 8) + (2 * 5))
      var result1 = operate1(calculator.add, operate1(calculator.subtract, 38), 
                                             operate1(calculator.multiply, 25));
      
      document.writeln('result1: ' + result1 + '<br/>');
                                            
      try {
        var result2 = operate2('add', operate2('subtract'38), operate2('multiply'25));
        document.writeln('result2: ' + result2 + '<br/>');
      } catch (e) {
        document.writeln(e + '<br/>');  
      }
 
      document.writeln('<br/>');
    </script>
  </body>
</html>
cs


# 함수에 함수 리터럴을 전달하는 익명함수

- 함수 리터럴을 이용해 정의한 함수를 이름 없는 함수, 즉 익명함수(unnamed function)라고 부름

- 이름이 없기 때문에 주로 변수, 객체 프로퍼티에 저장하거나, 함수의 인자 혹은 반환 값으로 주로 사용


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="utf-8" />
    <title>04-07</title>
  </head>
  <body>
    <script type="text/javascript">
      // 함수에 함수 리터럴을 전달하는 익명함수
      
      var calculator = {
        // operate 메소드의 첫번째 매개변수는 함수를 인자로 전달 받습니다.
        operate : function(method, operand1, operand2) {
          if (typeof method == 'function') {
            if (typeof operand1 != 'number' || typeof operand2 != 'number')
              throw new Error('operate(): 두번째, 세번째 매개변수는 반드시 숫자를 전달해야 합니다.');
            return method(operand1, operand2);
          } else 
            throw new Error('operate(): 첫번째 매개변수로 함수를 전달해야 합니다.');  
        }
      };
      
      try {
        // calculator.operate 메소드의 첫번째 매개변수로 익명함수를 전달합니다.
        var result1 = calculator.operate(function(x, y){ return x + y; }, 23);
        document.writeln('result1: ' + result1 + '<br/>');
        
        // 두번째, 세번째 매개변수로 숫자가 아닌 값을 전달하면 예외를 발생시킵니다.
        var result2 = calculator.operate(function(x, y){ return x + y; }, '2'3);
        document.writeln('result2: ' + result2 + '<br/>');
 
      } catch (e) {
        document.writeln(e + '<br/>');
      }
      document.writeln('<br/>');
      
      // 익명함수를 정의하고 바로 호출해 결과를 얻을 수도 있습니다.
 // 익명함수 즉시 호출 기법
      var result3 = (function(x, y){ return x + y;})(23);    //함수 선언과 동시에 (2,3)이 매개변수로 전달되어 함수 실행
      document.writeln('result3: ' + result3 + '<br/>');
      document.writeln('<br/>');
    </script>
  </body>
</html>
cs


# 중첩함수

- 자바스크립트에서 함수는 다른 함수 안에 중첩되어 정의될 수 있음

- 중첩함수(inner function)는 함수 내에서만 호출할 수 있으며, 함수 외부에서는 직접 호출할 수 없음

- 이런 특징으로 특정 함수에서만 필요한 기능을 외부에 노출시키지 않고 구현할 수 있으며, 함수 내부에 선언된 변수에 접근할 수 있기 때문에 객체지향의 정보은닉이라는 특징을 구현하는데 사용될 수 있음


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="utf-8" />
    <title>04-08</title>
  </head>
  <body>
    <script type="text/javascript">
      // 중첩함수
      
      function circle(radius) {
        var pi = 3.14;
        
        // 중첩함수는 내부 변수에 접근가능합니다.
        function area(r) {
          return r * r * pi;
        }
        
        // 중첩함수는 내부에서만 호출 가능합니다.
        return area(radius);    // radius 값은 r값이 된다
      }
      
      document.writeln('circle(5): ' + circle(5+ '<br/>');
      document.writeln('<br/>');
    </script>
  </body>
</html>
cs


# 스코프 체인

- 지역 스코프는 함수 단위로 관리되며, 이 지역 스코프를 관리하는 객체를 호출 객체

- 함수의 매개변수, 지역변수가 호출 객체의 프로퍼티

- 전역 스코프를 나타내는 객체를 전역 객체, 루트(root) 객체라고 함

- 전역 변수와 전역 함수는 전역 객체의 프로퍼티와 메소드

- var 키워드 없이 변수를 전역 객체에 등록되어 전역 변수가 되므로, 

  함수의 지역 변수로 선언하기 위해선 반드시 var 키워드를 사용해 변수를 선언해야 함

- 스코프 체인은 전역 객체와 함수 호출 시 생성된 호출 객체를 생성 순서대로 연결한 리스트

- 함수는 함수가 호출되는 시점을 기준으로 스코프 체인에 연결되어 있는 모든 것들에 접근 가능


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="utf-8" />
    <title>04-09</title>
  </head>
  <body>
    <script type="text/javascript">
      // 스코프 체인
      
      // 1. 전역 레벨의 파싱 결과 전역객체에 프로퍼티 x와 outer가 정의됩니다.
       
      var x = '전역 객체에 등록되어 있는 x 프로퍼티 값';
      
      function outer() {
        var y = 'outer 함수의 호출 객체에 등록되어 있는 y 프로퍼티 값';
        
        function inner() {
          var z = 'inner 함수의 호출 객체에 등록되어 있는 z 프로퍼티 값';
          document.writeln('x: ' + x + '<br/>');
          document.writeln('y: ' + y + '<br/>');
          document.writeln('z: ' + z + '<br/>');
        } 
        
        // 3. 함수 레벨의 파싱 결과 inner 함수에 대한 호출 객체에 arguments 프로퍼티가 초기화되고, 
        //    프로퍼티 z가 정의되고,
        //    outer 함수의 호출 객체와 inner 함수의 호출 객체 간에 스코프 체인이 연결되고,
        //    inner 함수의 코드를 실행합니다.
        //    이 때 x는 전역객체에, y는 outer 함수의 호출객체에, z는 inner 함수의 호출객체에 접근해서
        //    그 값을 취합니다. 
        inner();        
         
      }
      
      // 2. 함수 레벨의 파싱 결과 outer 함수에 대한 호출 객체에 arguments 프로퍼티가 초기화되고, 
      //    프로퍼티 y와  inner가 정의되고,
      //    전역객체와 outer 함수의 호출 객체 간에 스코프 체인이 연결된 후,
      //    outer 함수의 코드를 실행합니다.
      outer(); 
      
      document.writeln('<br/>');
    </script>
  </body>
</html>
cs


# 콜백함수

- 콜백함수는 직접 호출하는 함수가 아닌 어떤 특정 시점이나 조건을 만족했을 때 호출될 수 있도록 라이브러리 함수의 인자로 전달되는 함수를 말함. 즉, 특정 이벤트 발생시에만 수행되는 함수


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="utf-8" />
    <title>04-10</title>
  </head>
  <body>
    <script type="text/javascript">
      // 콜백함수
      
      function main() {
        
        var array = [];
        
        // 내장객체 Math의 random 함수는 0 ~ 1 사이의 값을 반환하고,
        // 내장객체 Math의 ceil 함수는 인자 값 이상의 최소 정수를 반환합니다.
        for (var i = 0; i < 10; i++) {
          array[i] = Math.ceil(Math.random() * 45);  
        }
        
        // work 함수를 호출하면서 첫번째 매개변수로 처리할 데이터 data를, 
        // 두번째, 세번째 매개변수로 콜백함수 even과 odd를 전달합니다.
        work(array, even, odd);
        
      }
      
      // 콜백함수 even은 짝수가 발견될 때마다 호출될 함수로 당시의 배열 인덱스와 원소를 출력합니다.
      function even(idx, num) {
        document.writeln((idx + 1+ '번째 데이터는 짝수 ' + num + '입니다.<br/>');
      }
      
      // 콜백함수 odd는 홀수가 발견될 때마다 호출될 함수로 당시의 배열 인덱스와 원소를 출력합니다.
      function odd(idx, num) {
        document.writeln((idx + 1+ '번째 데이터는 홀수 ' + num + '입니다.<br/>');
      }
      
      // work 함수는 매개변수로 전달받은 배열 data에서 
      // 짝수가 발견될 때마다 매개변수로 전달받은 콜백함수 callback1를 호출하고, 
      // 홀수가 발견될 때마다 매개변수로 전달받은 콜백함수 callback2를 호출합니다.
      function work(data, callback1, callback2) {
        for (var i = 0; i < data.length; i++) {
          if (data[i] % 2 == 0)
            callback1(i, data[i]);
          else
            callback2(i, data[i]);
        }
      }
      
      // main 함수를 실행합니다.
      main();
 
    </script>
  </body>
</html>
cs


# 비공개 속성/함수를 만들 수 있는 함수 클로저

- 클로저 : 실행될 코드와 함수의 유효 범위, 다시 말해 함수의 호출 객체와 연결된 스코프 체인의 조합

- 함수의 지역변수에 대한 중첩함수를 만들면 비공개 속성과 접근자 메소드를 구현해 객체지향의 정보은닉을 실현할 수 있음


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="utf-8" />
    <title>04-11</title>
  </head>
  <body>
    <script type="text/javascript">
      // 클로저
      
      // 1. 전역 레벨의 파싱 결과 전역객체에 프로퍼티 makeId와 id가 정의됩니다.
      function makeId() {
        var lastId = 0;
        
   // (익명)함수를 return한다 == 클로저
   // 중첩함수를 이용해서, 함수의 스코프 체인을 확장
        return function() { return ++lastId; };
      }
      
      // 2. 함수레벨의 파싱 결과 makeId() 함수에 대한 호출 객체에 arguments 프로퍼티가 초기화 되고,
      // 프로퍼티 lastId가 정의되고,  
      // 전역객체와 makeId() 함수의 호출객체 간에 스코프 체인이 연결된 후,
      // makeId() 함수가 실행되고, id는 익명함수를 반환받습니다.
      var id = makeId();
      
      // 3. 함수 레벨의 파싱 결과 id 함수에 대한 호출 객체에 arguments 프로퍼티가 초기화되고, 
      //    makeId 함수의 호출 객체와 id 함수의 호출 객체 간에 스코프 체인이 연결되고,
      //    id 함수의 코드를 실행합니다.
      //    이 때 lastId는 makeId 함수의 호출객체에 접근해서
      //    그 값을 취합니다.
      document.writeln('id: ' + id() + '<br/>');    // 1
      document.writeln('id: ' + id() + '<br/>');    // 2
      document.writeln('id: ' + id() + '<br/>');    // 3
      document.writeln('id: ' + id() + '<br/>');    // 4
      document.writeln('id: ' + id() + '<br/>');    // 5
      document.writeln('<br/>');
    </script>
  </body>
</html>
cs


- 출처 : SK Planet 상생혁신센터 javascript 교육과정


반응형

공유

댓글