JavaScript

값으로서의 함수와 콜백

값으로서의 함수

JavaScript에서는 함수도 객체다. 다시 말해서 일종의 값이다. 거의 모든 언어가 함수를 가지고 있다. JavaScript의 함수가 다른 언어의 함수와 다른 점은 함수가 값이 될 수 있다는 점이다. 다음 예제를 통해서 그 의미를 알아보자.

function a(){}

위의 예제에서 함수 a는 변수 a에 담겨진 값이다. 또한 함수는 객체의 값으로 포함될 수 있다. 이렇게 객체의 속성 값으로 담겨진 함수를 메소드(method)라고 부른다.

a = {
	b:function(){
	}
};

함수는 값이기 때문에 다른 함수의 인자로 전달 될수도 있다. 아래 예제를 보자.

function cal(func, num){
	return func(num)
}
function increase(num){
	return num+1
}
function decrease(num){
	return num-1
}
alert(cal(increase, 1));
alert(cal(decrease, 1));

10행을 실행하면 함수 increase와 값 1이 함수 cal의 인자로 전달된다. 함수 cal은 첫번째 인자로 전달된 increase를 실행하는데 이 때 두번째 인자의 값이 1을 인자로 전달한다. 함수 increase은 계산된 결과를 리턴하고 cal은 다시 그 값을 리턴한다.

함수는 함수의 리턴 값으로도 사용할 수 있다.

function cal(mode){
	var funcs = {
		'plus' : function(left, right){return left + right},
		'minus' : function(left, right){return left - right}
	}
	return funcs[mode];
}
alert(cal('plus')(2,1));
alert(cal('minus')(2,1));	

당연히 배열의 값으로도 사용할 수 있다.

var process = [
	function(input){ return input + 10;},
	function(input){ return input * input;},
	function(input){ return input / 2;}
];
var input = 1;
for(var i = 0; i < process.length; i++){
	input = process[i](input);
}
alert(input);

콜백

처리의 위임

값으로 사용될 수 있는 특성을 이용하면 함수의 인자로 함수로 전달할 수 있다. 값으로 전달된 함수는 호출될 수 있기 때문에 이를 이용하면 함수의 동작을 완전히 바꿀 수 있다. 인자로 전달된 함수 sortNumber의 구현에 따라서 sort의 동작방법이 완전히 바뀌게 된다.

function sortNumber(a,b){
    // 위의 예제와 비교해서 a와 b의 순서를 바꾸면 정렬순서가 반대가 된다.
    return b-a;
}
var numbers = [20, 10, 9,8,7,6,5,4,3,2,1];
alert(numbers.sort(sortNumber)); // array, [20,10,9,8,7,6,5,4,3,2,1]

비동기 처리

콜백은 비동기처리에서도 유용하게 사용된다. 시간이 오래걸리는 작업이 있을 때 이 작업이 완료된 후에 처리해야 할 일을 콜백으로 지정하면 해당 작업이 끝났을 때 미리 등록한 작업을 실행하도록 할 수 있다. 다음 코드는 일반적인 환경에서는 작동하지 않고 서버 환경에서만 동작한다. 동영상을 참고한다.

datasource.json.js

{"title":"JavaScript","author":"egoing"}

demo1.html

<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
</head>
<body>
<script type="text/javascript">
    $.get('./datasource.json.js', function(result){
		console.log(result);
	}, 'json');
</script>
</body>
</html>

 

댓글

댓글 본문
작성자
비밀번호
  1. pakimchi
    인자로 전달된 문자열 mode를 이용해서 funcs['plus']나 funcs['minus']를 리턴하기 위한겁니다.
    그렇게 리턴된 함수를 실제 사용하기 위해 뒤에 인자 리스트를 ()를 붙입니다.
    cal 함수는 인자를 하나만 받습니다.
    대화보기
    • 소라김
      콜백부분에 return값에 의해 배열이 재배치되는 부분이 많이 헷갈려요 ㅠㅠ 댓글에서도 이 부분을 많이 헷갈리시는거같은데 명확하게 정리된 완료버전이 있음 더 좋을거같아요! 그래도 덕분에 공부에 좀 더 진전이 나아가는 느낌이네요. 늘 감사합니다.
    • 너나
      function cal(mode){
      var funcs = {
      'plus' : function(left, right){return left + right},
      'minus' : function(left, right){return left - right}
      }
      return funcs[mode];
      }
      alert(cal('plus')(2,1));
      alert(cal('minus')(2,1));

      cal이라는 함수안의 mode라는 인자가 들어가는 것은 압니다. funcs라는 객체안의 key값인 plus와 minus가 함수로
      사용된것도 이해가구요
      하지만
      첫번째 질문 : 이부분 "return funcs[mode];" funcs라는 객체에 []가 왜 사용된건가요?
      두번째 질문 : 함수 cal인자가 cal(A,B)이런 형태로 들어가야하는것인데 ,cal('plus')(2,1)이런 형태를 띄는 이유가 무엇인가요?
      설명부탁드립니다
    • cse7600
      콜백

      jquery를 이용하려면,
      head 사이에
      <script src = "//code.jquery.com/jquery-1.11.0.min.js"></script>
      이렇게 넣어주면 된대 !


      $.get(url,url로 불러온 데이터를 이용해서 하려는 행동(함수),저장되는 데이터 형태);


      그리고 $는 jquery 호출?하는 기호 ? 함수래
      크 어렵구만.
    • cse7600
      180912
    • 제가생각하는답
      제 생각으로는 객체를 이용하긴 하지만, 그 속에는 함수를 호출하는 부분도 있기 때문에
      함수호출하는 부분을 생각하면 코드를 객체명['키값'](함수의 매개변수); 의 형식이 되어야하기때문에
      객체명['키값'].키값(함수의 매개변수); 형식은 어긋나므로 실행이 안되는것이라 생각되네요

      alert부분을 자세히 뜯어보면
      크게 보면 cal( )이라는 함수가 덮고있고,
      세부적으로보면 func[mode](매개변수);의 형식이 안에 들어가 있기때문에
      질문하신분의 생각에는 앞부분인 func[mode]부분인 객체호출에만 초점이 맞춰계시지만,
      뒷부분까지 본다면 매개변수를 가지고있는 함수호출 부분이 있기때문에
      func[mode].plus(2,1)은 문법적으로 틀린것이라 생각됩니다.

      개인적으로 뜯어보고 생각해보다가 생각난 부분이라 틀릴 수 있지만
      조금이나마 다르게 생각해볼 수 있는 기회는 되셨기를..
      대화보기
      • / 계속 보기 /

        감사합닏. 계속 봐야 할 영상.. 내 머리가 이리도 멍충했는가..ㅠㅠㅠ
      • 정말 주옥같은 중요한 개념들을 알기 쉽게 설명해 주십니다.
        대단히 감사합니다.
      • ohaeyoon@gmail.com
        감사합니다.
      • 오랜만에 다시 보니 이해가 더 잘가는? 느낌이에요.
        콜백함수 하면 어렵게만 생각했는데, 내장 메소드의 인자로 사용자가 함수를 만들어서 얼마든지 활용할수 있다는 개념이 맞는지요?
      • anomyous
        funcs.plus() 나 return funcs.minus() 는 함수가 있지만 funcs.mode() 라는 함수는 funcs 객체에서 존재하지 않기 때문에 오류가 날껍니다.
        그래서 객체에서 배열 형식으로 변수를 입력받아 함수를 지정할 수 있게 하려는 것 같습니다.
        대화보기
        • 공명제갈
          function cal(mode){
          var funcs = {
          'plus' : function(left, right){return left + right},
          'minus' : function(left, right){return left - right}
          }
          return funcs[mode]; // 이부분!!!!!!!
          }
          alert(cal('plus')(2,1));
          alert(cal('minus')(2,1));


          여기서 이부분으로 표시한 부분을 return funcs.mode 로 하면 안되는데 혹시 어떤이유때문에 그런것인가요??ㅠㅠ
          초보라 아시는분 있으시면 쉽게 설명해주시면 감사하겠습니다.
          제가 공부한 바로는 a객체의 b키값 에서
          a['b']로 접근하는 것과 a.b로 접근하는게 같다고 생각하고 있었는데 아닌가요?
        • 안장호
          강의자료 감사합니다~! ^^
          그리고 아래에 선택정렬(?)애 대해 설명 해 주신 '지나가다가'님께도 감사드립니다~! ^^
        • 히스토
          감사합니다
        • 듀티프리
          좋아요. 감사합니다.
        • 코딩잘하고싶어요 ㅎ
          후반에 멍 때릴 뻔했습니다. ㅠㅠ 난이도는 조~금 어렵지만 그만큼 풍부한 내용이네용 ^^
        • 김진홍
          감사합니다~~
        • 박재현
          4/3까지 공부
        • 박인호
          12-13
          수강완료.
        • Jupi
          콜백함수 - 함수가 다른 함수의 인자로 사용됨으로써 그 함수의 내용을 완전히 바꿀 수 있는것.
          비동기(Asynchronous) - 요청에 처리 완료와 관계없이 응답한다. 이후 운영체제에서 응답할 준비가 되면 응답한다.

          이걸 좀 머리에 그려지도록 이해할려면, jQuery를 언능 배워야 겠군요. ㅎㅎ

          그리고, 밑에 정렬 알고리즘을 찬찬히 설명해주신 지나가다가님 고맙습니다!
        • 고스트프리
          감사합니다.
          대화보기
          • 고스트프리
            진행중
          • 수복
            좋은 설명 감사합니다.
          • GoldPenguin
            완료했습니다.
          • momo
            마지막 과제를 전에 '웹브라우저 자바스크립트' jQuery Ajax 강의에서 배운 대로 아래와 같이 해봤더니 잘 작동하였습니다.
            $.ajax({
            url: './datasource.json.js',
            dataType: 'json',
            type: 'GET',
            success: function(result){
            console.log(result);
            }
            });

            감사합니다!
          • 호이소이
            좋은 설명 감사합니다
            대화보기
            • Jeong Min Lee
              좋은 강의 감사드려요~!
            • 지나가다가
              구체적인 정렬 알고리즘은 프로그래밍 초심자가 이해하기 어려워서
              이고잉님께서 일부러 설명을 스킵하신 것 같은데...
              밑에 잘못된 정보가 있어 제가 굳이 설명을 보탭니다.

              우선 [20, 10, 9,8,7,6,5,4,3,2,1]의 배열에서 a-b라는 연산을 모두 한 다음
              그 결과값으로 정렬하는 것이 결코 아닙니다.
              뭐하러 굳이 뺄셈을 하고 그 값으로 또 정렬하겠습니까?

              자바스크립트의 정확한 알고리즘은 아니지만
              쉽게 정렬 알고리즘을 설명하면 이렇습니다.

              (a,b) 형식으로 지정한 두 인자를 차례로 비교합니다.

              우선 배열 numbers[0]과 numbers[1] 즉, 20과 10을 비교해 볼까요?
              20-10 = 10
              결과값이 10 즉, 양수입니다.
              sort함수에 sortNumber(a,b)의 return 값으로 양수 10을 전달합니다.
              그럼 sort함수가 양수값을 전달받고 배열의 순서를 바꾸어 버립니다.
              (정확하게 말하면 두 배열 안에 든 값을 교체)
              그럼 배열이 [10, 20, 9,8,7,6,5,4,3,2,1] 이렇게 바뀝니다.

              그 다음 numbers[0]과 numbers[2] 즉 10과 9를 비교합니다. 10 - 9 = 1 >0, 양수입니다.
              결과값이 양수이므로 또 10과 9의 순서를 바꿉니다.
              이런 식으로 계속 두 인자를 비교해서 결과값이 양수가 나오면 순서를 바꾸고,
              음수가 나오면 순서를 그대로 유지하는 겁니다.

              배열이 바뀌어가는 순서를 보면 이해하기 쉽습니다.

              [(20), (10), 9,8,7,6,5,4,3,2,1] 20-10 = 10, 즉 양수이므로 순서바뀜! ()는 비교되는 인자값.
              [(10), 20, (9),8,7,6,5,4,3,2,1] 10 - 9 = 1 또 양수, 순서 바뀜.
              [(9), 20, 10, (8),7,6,5,4,3,2,1] 반복...
              [(8), 20, 10, 9,(7)...]
              ...
              [(2). 20, 10...3, (1)]
              [(1), 20, 10...]

              그럼 배열 내에서 가장 작은 값 1이 찾아지겠죠.

              [1, 20, 10, 9,8,7,6,5,4,3,2]

              1의 순서는 바뀌지 않습니다. 1-2 = -1
              즉 결과값이 음수이기 때문이죠.

              그 다음은 두번째 배열 차례입니다.
              20 - 10 = 10 > 0 이므로 순서를 또 바꿉니다.

              [1, (20), (10), 9,8,7,6,5,4,3,2]
              [1, (10), 20, (9), 8...]
              [1, (9), 20, 10, (8)...]

              이런 식으로 반복하다 보면 두번째로 작은 값 2도 찾게 됩니다.

              ....
              [1, 2, 20, 10, 9,8,7,6,5,4,3]

              그럼 다음은 세번째...
              이렇게 지루하게 반복하면 결국 정렬이 됩니다.

              물론 실제 자바스크립트에서는 비교하는 순서가 다릅니다.
              다른 알고리즘을 쓰기 때문이죠.

              이렇게 차례차례 비교해 나가면 인간이 이해하기는 쉽지만
              연산량이 기하급수적으로 늘어나기 때문에 다른 정렬 알고리즘을 쓰는 것이죠.

              실제로는
              [20, 10, 9,8,7,6,5,4,3,2,1]
              배열의 양쪽 끝부터 비교하고 (20, 1),
              그 다음 배열의 가운데 값을 차례로 비교해 나갑니다. (1,6)
              디버깅해 보시면 쉽게 아실 수 있을 겁니다.
            • Dong Il Kim
              var numbers = [20, 10, 9,8,7,6,5,4,3,2,1];
              function sortNumber(a,b){
              return a - b;
              }
              를 하게 되면 모든 값들끼리 a - b를 하게 됩니다.

              그렇게 나온 값들을 sort()에 넣으면, (a - b)의 순서가 숫자가 낮은 것부터 높은 순서대로 정렬이 되겠죠.
              -19(1 - 20), -9(1-10), -8(1-9), -7(1-8), -6(1-7), -5(1-6), -4(1-5), -3(1-4), -2(1-3), -1(1-2)
              -18(2-20), -8(2-10), -7(2-9), -6(2-8), -5(2-7), -4(2-6), -3(2-5), -2(2-4), -1(2-3), 0(2-2), 1(2-1)
              -17(3-20), -7(3-10), -6(3-9), -5(3-8), -4(3-7), -3(3-6), -2(3-5), -1(3-4), 0(3-3), 1(3-2), 2(3-1)
              ...
              10(20-10), 11(20-9), 12(20-8), 13(20-7), 14(20-6), 15(20-5), 16(20-4), 17(20-3), 18(20-2), 19(20-1)

              그럼 계산된 숫자의 크기에 따라서 a와 b의 순서가 sort()에 의해 재배열 되어
              1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20
              가 나옵니다.
              대화보기
              • namimoon
                세 번째 sortfunc 함수의 기능은 이해가 가지만, console.log(a,b) 의 결과값이 찍히는 이유를 정확히 모르겠네요.
              • 세븐나이츠
                어렵네요 나중에 다시 봐야겠어요
              • Seo Yun Seok Tudoistube
                이해하는거랑 아는거는 다르다는데, 이해했다고 생각하는거랑 이해한거랑도 다르겠죠^^;; 감사합니다^_____^!!!
              • enjoyPG
                음 저도 같은 현상이네요.
                크롬 개발자 도구에서는 또 정상적으로 값이 나오는데

                저는 Visual studio code쓰고 있는데 ide에서는 undefined가 뜨네요 ;; 허허
                대화보기
                • crable
                  감사합니다
                • 이승우
                  20170521 완료
                • 남경진
                  너무 어렵게 생각하지 않아도 되요!
                  대화보기
                  • 이승준
                    콜백 참 어렵네요... 한참 들여다 봐야 하는 듯..
                    정확하진 않겠지만, 대략 제가 이해하기로는..
                    sort의 인자로 콜백되는 함수의 포맷이... function(a, b)인데,,,
                    이때 각 배열의 값들을 가져와서 대조한다.
                    이때 a, b 값들을 비교해서 -1(음수), 0, 1(양수) 로 각각 리턴하는 방식이라는 거죠.

                    a<b 이면 -1(음수) 즉 a에 b보다 한단계 적은 인덱스를 부여하고
                    a=b 이면 0 즉 정렬상태를 그대로 두고
                    a>b 이면 +1(양수) 즉 a에 b보다 한단계 큰 인덱스를 부여해서 왼쪽에서 작은 값부터 순차정렬한다

                    그런데 리턴값을 -1은 곧 음수이고, +1은 곧 양수라고 보면
                    숫자를 정렬할 경우,
                    a-b에서 a<b이면 음수이고, a>b이면 양수니까 위의 내용과 동일하게 된다.
                    따라서 return a-b 하나의 명령으로 처리될 수 있다.
                    이것을 리턴값(-1 0 1)을 기준으로 정리하면 .
                    1) 음수 -1 : a를 b보다 왼쪽에 정렬
                    (1) a-b=음수 -> a<b : 순차
                    (2) b-a=음수 -> a>b : a가 b보다 큰데 b의 왼쪽에 배열되므로 역순차
                    2) 0 배열 유지
                    3) 양수 +1 : a를 b보다 오른쪽에 정렬
                    (1) a-b=양수 -> a>b : 순차 t
                    (2) b-a=양수 -> a<b : a가 b보다 작은데 b의 오른쪽에 배열되므로 역순차

                    이렇게 이해해도 문제 없나요? ^^;;
                  • 이승우
                    20170516 2/4까지 완료
                  • 최규선
                    20170430완료! 감사합니다.
                  • 김소희
                    감사합니다!
                  • 신입1
                    오랜만에 복습중인데 지금은 너무 쉽게 느껴져서 뿌듯하네요
                  • BANIP
                    비동기적인 처리 => 인터페이스와 사용자가 소통할 범위와 시간을 늘리기위해 시간이 많이 걸리는 작업을 뒤로 미루는 처리
                    순차적 절차적으로 코드를 일직선으로 쭉 실행하는것을 동기적인 처리, 우선도에 따라 다르게 처리하는것을 비동기적인 처리라고 부름.
                  • Sang Jin Lee
                    좋은 강의 감사합니다~!!
                  • Joohan Lee
                    자바스크립트에서 함수는 값으로 사용 가능. 그런 특성 덕분에 어떤 함수에 다른 함수를 데려와서 새로운 기능의 함수로 동작하게 할 수 있다. 어떤 함수의 새끼함수로 작동하는 함수를 메소드라 하며, 함수에 점(.) 붙여서 불러쓴다. 함수의 인자로 불러와서 쓰는 함수는 콜백 함수라 한다.
                  • 초보
                    컴퓨터 언어는 생전 처음인데 계속해서 잘 따라오다가 처음으로 막히네요.
                    아예 이해가 안되는건 아니고 설명을 하면 눈으로 따라가면서
                    논리적으로 따라가기는 하는데 뭔가... 많이 답답한 느낌...
                    딱 이 수업이후로 갑자기 머릿속이 복잡해지면서ㅋㅋ 함수 객체 메소드 이런것들이 갑자기 뭉탱이로 느껴지고
                    어떻게 다르다는건지 잘 이해가 안되요.
                    저 식들이 목적을 향해 서로가 연결되는 논리가 뭐랄까 그냥 규칙이랄게 없이 마구잡이로 막 연결되는 느낌이에요.
                    제눈엔 그냥 안에든 배열갯수만 다르지 다 똑같은 함수같이 보여요.ㅠㅠ 개발자들은 더 자유롭고 더 융통성있게 운용할수는 있을것 같은데 처음 배우는 입장에서는 참 곤란하네요..ㅠㅠ
                  • Ruin09
                    요지는 function(result){
                    console.log(result); <-- 이 부분이 동기적으로 작동하는게 아니고 비동기적으로 작동한다는 말씀이시죠?
                  • 폭스킴
                    이 챕터가 초보자에겐 깔딱고개군요;;
                    강좌 다시 한 번 더 들어보고, 댓글들 읽어보고, 검색도 좀 해보니까 조금 정리가 되는 것 같아요;;
                    제가 보기에 이 챕터는 동기, 비동기(ASYNCRONOUS)를 이해하느냐 못하느냐가 관건인 것 같습니다.
                    비동기처리를 위해선 값으로서의 함수(FIRST CLASS CITIZEN)이라는 개념이 유용했고,
                    다른 함수의 매개변수로써의 CALL BACK함수를 통해 사용자의 비지니스 로직을 처리하도록 위임한다.
                    제가 정리한 게 맞나요?
                  • 임지호
                    값으로서의 함수 : 자바스크립트에서 함수는 값으로도 쓰일 수 있다(변수에 담기, 객체 안에 저장하기, 다른 함수의 인자로 사용하기, 함수의 리턴값으로 사용하기, 배열의 값으로 사용하기 등) -> first-class-object,citizen이라함
                    *객체 안에서 key는 변수 역할, 속성이라고도 부르고 value에 함수가 담긴다면 이는 메소드라 부른다
                    - 콜백함수 : 함수가 다른 함수의 인자로 사용됨으로써 그 함수의 내용을 완전히 바꿀 수 있는 것.
                    - 비동기처리 : 시간이 오래 걸리는 작업을 나중에 처리해서 일련의 작업을 순서대로 처리하지 않음으로써 사용의 편의성을 높이는 기법.(일반 환경에서는 보이지 않고 서버 환경에서 구동된다) - 대표적으로 Ajax라는 기법이있음
                  • 박영광
                    그러니까 상단의 메뉴나 알림을 누르면 웹브라우저가 서버에서 정보를 읽어와서 창에 띄우는 작업을 완료할때까지 다른 모든 활동을 정지하는게 아니라 마치 이메일을 예약했는지 여부를 확인하는 프로그램이 백그라운드에서 돌아가고 있는 것처럼 사용자가 다른 일을 하는 와중에 그런 작업을 한다는 것이죠?

                    그리고 그런 일을 가능하게 하는 기법이 javascript에서 미리 만들어논 함수의 인자값으로 또다른 함수를 전달하는 콜백기법이고요.
                    또 그런 콜백기법을 이용해서 사용자가 다른 활동을 하는동안 프로그램이 백그라운드에서 필요한 작업을 처리하게 하는 기법이 ajax이고요
                  • 허민호
                    먼소린지 모르겠지만ㅜ 공부좀 더하고 다시보러 오겠습니다
                  버전 관리
                  egoing
                  현재 버전
                  선택 버전
                  graphittie 자세히 보기