JavaScript

함수의 호출

함수호출

함수에 대한 기본 수업에서 함수를 호출하는 방법을 알아봤다. 아래는 함수를 호출하는 가장 기본적인 방법이다.

function func(){
}
func();

JavaScript는 함수를 호출하는 특별한 방법을 제공한다. 본 토픽의 시작에서 함수를 객체라고 했다. 위의 예제에서 함수 func는 Function이라는 객체의 인스턴스다. 따라서 func는 객체 Function이 가지고 있는 메소드들을 상속하고 있다. 지금 이야기하려는 메소드는 Function.apply과 Function.call이다. 이 메소드들을 이용해서 함수를 호출해보자. 결과는 3이다.

function sum(arg1, arg2){
    return arg1+arg2;
}
alert(sum.apply(null, [1,2]))

함수 sum은 Function 객체의 인스턴스다. 그렇기 때문에 객체 Function 의 메소드 apply를 호출 할 수 있다. apply 메소드는 두개의 인자를 가질 수 있는데, 첫번째 인자는 함수(sum)가 실행될 맥락이다. 맥락의 의미는 다음 예제를 통해서 살펴보자. 두번째 인자는 배열인데, 이 배열의 담겨있는 원소가 함수(sum)의 인자로 순차적으로 대입된다. Function.call은 사용법이 거의 비슷하다 여기서는 언급하지 않는다.

좀 더 흥미로운 예제를 살펴보자. 결과는 6과 185이다.

o1 = {val1:1, val2:2, val3:3}
o2 = {v1:10, v2:50, v3:100, v4:25}
function sum(){
    var _sum = 0;
	for(name in this){
		_sum += this[name];
	}
	return _sum;
}
alert(sum.apply(o1)) // 6
alert(sum.apply(o2)) // 185

예제가 복잡해보이지만 한나씩 분해해서 생각해보면 어렵지 않다.

우선 두개의 객체를 만들었다. o1는 3개의 속성을 가지고 있다. 각각의 이름은 val1, val2,val3이다. o2는 4개의 속성을 가지고 있고 o1과는 다른 속성 이름을 가지고 있고 속성의 수도 다르다.

그 다음엔 함수 sum을 만들었다. 이 함수는 객체의 속성을 열거할 때 사용하는 for in 문을 이용해서 객체 자신(this)의 값을 열거한 후에 각 속성의 값을 지역변수 _sum에 저장한 후에 이를 리턴하고 있다.

객체 Function의 메소드 apply의 첫번째 인자는 함수가 실행될 맥락이다. 이렇게 생각하자. sum.apply(o1)은 함수 sum을 객체 o1의 메소드로 만들고 sum을 호출한 후에 sum을 삭제한다. 아래와 비슷하다. (실행결과가 조금 다를 것이다. 그것은 함수 for in문으로 객체 o1의 값을 열거할 때 함수 sum도 포함되기 때문이다.)

o1.sum = sum;
alert(o1.sum());
delete o1.sum();

sum의 o1 소속의 메소드가 된다는 것은 이렇게 바꿔 말할 수 있다. 함수 sum에서 this의 값이 전역객체가 아니라 o1이 된다는 의미다. 일반적인 객체지향 언어에서는 하나의 객체에 소속된 함수는 그 객체의 소유물이 된다. 하지만 JavaScript에서 함수는 독립적인 객체로서 존재하고, apply나 call 메소드를 통해서 다른 객체의 소유물인 것처럼 실행할 수 있다. 흥미롭다.

만약 apply의 첫번째 인자로 null을 전달하면 apply가 실행된 함수 인스턴스는 전역객체(브라우저에서는 window)를 맥락으로 실행되게 된다.

댓글

댓글 본문
  1. Yongbeom Kwon
    완료
  2. dasjnfal
    이 강의를 수강하는 시점에 있어서 this라는 개념에 대한 부분을 짚기 않았기 때문에 apply라는 메소드를 설명함에 있어서 편의상 객체o1안에 sum이라는 함수를 넣는것과 비슷하다고 설명하신 것 같아요. 함수를 선언하는 시점에 따로 this를 지정해주지 않으면 그 함수 내부에서 this는 window 입니다. 즉, apply는 특정 함수를 어떤 this위에서 굴릴지 적용하는 메소드인 것 같아요.

    이해하기 쉽게 알려주시려고 하는 egoing님의 노력이 보여서 정말 존경스럽네요.
  3. dasjnfal
    sum함수를 선언할 시점에 this는 window 아닌가요?
  4. 코딩중독
    아 상당히 어렵네요 ㅎㅎㅎ
  5. 준식
    20200606 진행중
  6. 아기별
    *마지막 예제 정리 : 틀리면 말해주세요. 설명해주신 분들 모두 감사합니다..ㅠㅠ

    - 함수 sum을 호출하기 위해 sum.apply(o1)를 쓴다.

    - o1을 sum.apply의 인자로 주게 되면
    sum.apply(o1)은 독립적으로 있던 함수 sum을
    객체 o1에 속하게 하여 method로 만들고
    그렇게 sum.apply(o1)가 o1.sum()이 되어 동작을 하게 되면
    sum을 o1에 속하지 않게 한다. (안그러면 sum함수의 내용도 다 더해버리니까..)

    - method sum함수에 함수인자로 들어온 o1은
    this=함수인자이므로 sum의 this로 들어가게 된다.

    즉, 어떠한 객체와 독립적으로 존재하는 함수를
    함수명.apply(객체명)로 불러내면

    그 순간 그 함수는 그 객체의 method가 되어
    객체명.함수명을 한 샘이 되는 것이다.

    (원래는 객체 안에 함수가 들어있는 관계-함수가 method인 경우-여야지
    객체명.함수명으로 호출이 가능한건데
    apply를 통해 그렇게 호출한 샘으로 치는 것이다.)

    이렇듯 javascript에서 함수는 apply나 call이라는 method를 통해
    다른 객체의 소유물인것처럼 실행할 수 있다.
  7. 한강
    감사합니다. 200316!
  8. 완료
  9. moleskindiary@gmail.com
    감사합니다!
  10. 현수
    감사합니다
  11. 오현주
    2019.12.20 수강완료
  12. 굼벵이
    완료
  13. 호영킴
    처음엔 이해가 안되서 뭐지,, 도대체 뭐지,,, 배우지 말고 넘어갈까 이러다가

    막상 이해하니 유용한 기능이라고 생각합니다.

    제가 이해하는데 추가로 본 웹페이지 공유 드립니다.

    https://beomy.tistory.com/4

    참고하셔요 (블로그 광고 이런거 아닙니다..^^)
  14. 홍주호
    20191026 완료
  15. 박창신
    완료
  16. 김종선
    이해는 됬는데 이걸 써먹을수가..있을런지...일단 익혀봅니당......
  17. woong2019
    이거 어디에 쓰는지 이해가 안가네요? 많이 쓰는 건가요?
  18. lsm99999
    o1, o2 객체에 들어가는 sum : sum 의 왼쪽 sum은 o1, o2 객체의 속성(property)명이 되고 오른쪽 sum은 미리 만들어놓은 함수(function) sum 입니다.

    이렇게 하면 apply 함수를 이용하지 않고도 o1.sum() 을 통해 sum 함수를 실행할 수가 있습니다.
    대화보기
    • 이채
      점점 한번에 이해하기 어려워지는군요.
      검색을 해보니, 자바스크립트는 기본 범위가 window로 설정되어 있기 때문에 apply 함수를 사용하지 않고 그냥 호출하는 경우 this의 기본값이 window가 되어 의도하지 않는 값을 호출하는 듯 합니다.
      apply(null, [a,b])를 입력했던 이유는, 첫번째 항목에 null을 입력하면 window 값을 그대로 사용한다는 의미이고..
      여기에서 this를 window가 아니라 내가 실제 사용하고자 하는 o1, o2 값으로 바꾸기 위해서 apply 함수를 사용한다.
      이렇게 이해하면 맞는 것인지... 정리하면서도 헷갈리네요.
      뒷부분을 더 들으면 정확히 이해가 되려나요?^_ㅠ
    • skqmekd
      sum 클릭했을때 sum 이 다중 선택되게하는 키는 어떤거 누르면 되나요?>
    • choon
      감사합니다.
    • 미완성
      20190109
    • 라라라
      dj_jang님 첩자님 주도현님 다들 감사합니다
    • 주도현
      애초에 함수 sum이 인자가 없이 설정되었기 때문입니다.
      Sum();에 인자로 o1을 넣더라도 에러는 나지 않을 것 같습니다.
      다만
      Sum함수 안의 this는 sum함수를 소유하고 있는 객체인데
      그냥 함수를 호출하면 전역객체가 해당 함수를 소유하고 있는게 됨으로
      Name in this라는 문장이 전역객체인 window의 특성하고
      맞지 않아서 에러가 나는 것으로 생각됩니다.
      Window나 ~ in ~ 의 문법은 잘 몰라서 이 강의 내용을 토대로만 이해한대로 생각해보았습니다.
      대화보기
      • 스탐
        감사합니다.
      • 첩자
        apply의 경우 매개변수로 o1이 들어가는데 sum함수에도 o1을 넣고 this 대신 o1을 쓰신다면 됩니다
        function sum(o1) {}
        대화보기
        • dj_yang
          인자를 얼마 넣을 지 모를 때 사용하는 메소드가 apply 입니다.

          만약, 그냥 sum(o1);을 쓰고 싶다면 처음 함수를 만들 때 그에 관련한 매개변수를 정의해주셔야합니다.

          그게 아니라면 sum.apply(o1); 을 사용하시면 됩니다.

          이게 완벽한 정답이 아니지만 이런 식으로 생각하시면 편할 거에요..
          대화보기
          • 라라라
            아래 구문은 이고잉님이 예제로 사용하신 구문입니다.
            이 함수를 호출할 때

            sum(o1);

            이라고 호출하면 에러가 나는 이유는 무엇인가요?
            즉 sum(o1);이라고 했을 때 o1을 this로 받아들이지 못하는 이유는 뭘까요?

            결과론적으로 안된다는 것은 확인했습니다. ㅎㅎ
            다만 이유가 궁금해서요!

            아시는 분들 계신가요?



            ------------------------------------------------

            o1 = {val1:1, val2:2, val3:3}
            o2 = {v1:10, v2:50, v3:100, v4:25}

            function sum(){
            var _sum = 0;
            for(name in this){
            _sum += this[name];
            }
            return _sum;
            }
          • moon
            감사합니다!
          • <script type="text/javascript">
            o1 = {val1:1, val2:2, val3:3, sum : function(){
            var result = 0;
            for( item in this){
            if(typeof this[item] !== 'function')
            result += this[item];//this에는 function이 포함된다.
            }
            return result;
            }}

            alert(o1.sum());
            //o1.sum은 function임. 고로, function 내용을 가져옴.
            //o1.sum()은 sum+function()임.
            </script>
          • bbomy
            sum:sum 부터 이해가 안되서 계속 다시보기 하고있네요ㅠ

            혹시 설명해주실 수 있나요??ㅠㅠ
          • 안장호
            감사합니다~! ^^
          • 안젤리나
            무슨말인지 모르겠어요..산너머산 ㅠ
          • 샐린저
            자바 하다가 배우고 있는데 신기하네요. call 함수도 설명해주세요~ ^^
          • 네로렌
            함수를 객체처럼 사용하니 헷갈리는 점이 많네요 @@;;
          • 김띵띵
            무슨 이런 황당한 문법이..
            strict한 언어만 보다가.. 이런 언어를 보니 적응이 안되네요..ㅎㅎ
          • sigurnna
            문법이 뭔가 충격이다...
          • 코딩잘하고싶어요 ㅎ
            저도 동감합니다. 내용은 어렵지만 차차 이해되길 바랄 뿐이죠..
            대화보기
            • 박인호
              12-15
              수강완료.
              이해는 됐지만 어디서 사용하면 되겠다 하는 생각은 떠오르지 않네요.
              웹브라우저 자바스크립트 수업에서 실용적인 예제가 있길 바라겠습니다.ㅎ
            • Jupi
              참 자유롭습니다. 갑자기 함수를 객체에 넣어다 빼고...
              객체에는 수치 데이터만 집어 넣어두고, 함수를 적용시키고 싶을때만 결합시켜서 써도 될듯 하네요!
            • 감사합니다.
              와... 저도 그 부분이 궁금했었는데 감사합니다.
              대화보기
              • Yoonho Aaron Kim
                네 아래 링크 확인해보세요.
                https://opentutorials.org......491
                대화보기
                • for in문이 이전 수업에 있었던가요? ...
                • 수복
                  잘보았습니다.
                • GoldPenguin
                  완료했습니다.
                • Jeong Min Lee
                  좋은 강의 감사합니다.
                • publicum
                  두번째 동영상 중간에 apply를 사용하지 않는 경우의 코드에 {}이 없는 if 문이 있길래 궁금증이 생겨 검색을 해봤습니다.혹시 저처럼 궁금해하시는 분이 있을까 해서 적어둘게요.

                  한 줄짜리 명령에 한해서는 {}없이 if-else 구문을 작성해도 동작에는 문제가 없습니다. C, JAVA, PHP등의 다른 언어도 마찬가지이고요.
                  하지만, 추후에 본인 혹은 다른 사람이 해당 코드를 확장해서 두 줄 이상이 되면 반드시 {}표시로 감싸줘야합니다.
                  따라서 한 줄짜리 문장이라도 처음부터 {}로 감싸주는 것이 좋은 습관이라고 합니다.
                • Yoonho Aaron Kim
                  좋은 강의 감사합니다.
                  javascript 강의를 쭉 보고 있는데... 함수가 javascript의 "꽃" 이란 생각이 문득 드네요...
                • Seo Yun Seok Tudoistube
                  이럴때 유레카(Eureka) 라는 말을 찾고 싶어집니다. 감사합니다^_____^!!!
                • crable
                  감사합니다.
                버전 관리
                egoing
                현재 버전
                선택 버전
                graphittie 자세히 보기