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. 김명수
    ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
    대화보기
    • 완료!
      완료! 감사합니다~
    • 카구
      Java 객체의 개념을 이해하고 오시면 더 좋을 것 같아요!!!
      객체에 대한 이해를 하고 오시면 조금 난해할 내용들이 명확하게 보일 수 있습니다!!!
      대화보기
      • 아브아카
        클로저부터 급 난이도 상승했네요.
        이게 뭔가 현실적으로 쓰이는 상황이 있을텐데,
        너무 쉬운 예제로 원리만 설명하다보니 왜 저렇게 쓰는건지, 어떨때 써야되는지 전혀 감이 안옵니다.
        계속 보다보면 언젠가 필요한 상황이 오겠죠? ㅠ.ㅠ
      • delete o1.sum(); 이아니고
        delete o1.sum 아닌가요??

        맨위와같이 하면 값이 비워지지않고 계속 출력되네요
        ex :
        alert(o1.sum());
        delete o1.sum();
        alert(o1.sum());
      • 함수를 객체의 메소드화 시킨다는 거군요.
      • yihsang
        감사합니다.
      • 구블리
        어렵네요 ㅠ
      • 지영
        누우가 자바스크립트 쉽다 그랬어 때려줄거야 흐으윽
      • 이주환
        2016. 04. 24

        잘보고갑니다.
      • JustStudy
        고맙습니다.
      • Byeong Koo Kang
        이해가 되면서도.. 뒤돌아서면 까먹을 것만 같다는..

        계속 복습해봐야겠네요.
      • WayneKing
        흥미롭네요.
      • 고고
        함수를 가져다가 특정 객체의 익명함수처럼 사용한다는 얘기군요.
        객체에 속했다가 delete되니까 익명함수보다는 메소드라고 해야겠네요.

        뒤에 객체지향을 듣진 않았지만 지금까지 자바스크립트에 대해서 느낀건
        좋게 말하면 자유로운 문법을 가진 언어인데 나쁘게 얘기하면 체계가 없다는.....
        아마도 웹의 동작을 코딩하는데 집중하기 위해서 함수에 자유도를 더 준거 같네요
      • 이경호
        sum.apply라는 함수를 만들고 그 함수를 객체에 붙여서 객체의 함수처럼 사용하려고 할때 사용하는군요!
      • 행복한빛
        점점 어려워지네요. 눈이 핑핑돌아요 @_@ 이렇게 쉽게 설명해주시는데, 배우는 입장이 매번 그렇듯이 ㅎㅎ
        매번 잘 듣고 있습니다.
      • 딩구르르
        정말 매번 너무 감사합니다.
        그런데 "sum을 객체 o1의 메소드로 만들고 sum을 호출한 후에 sum을 삭제한다." 말씀해주셨는데,
        호출 후에 sum을 삭제하지 않고 고정으로 o1의 객체에 sum메소드를 속성으로 넣는 내장 메소드는 없는 건가요?
        이고잉님이 설명해주신 것처럼 o1의 객체에 직접 sum메소드를 추가하는 방법 밖에 없나요?
        그냥 갑자기 생각난 부분인데 o1 객체에 어떤 특정 이벤트가 있을 때(코드 실행중에 클릭 이벤트를 줬을 때) sum이라는 메서드를 추가하고 싶은데 이럴땐 어떻게 해야하나요?
      • gohu517
        실무로 일하면서 잘 알지 못하고 자바스크립트를 써왔던 것 같습니다. 강의를 들으면서 개념을 배우고 정리가 되어 강의 듣는 것이 너무 즐겁습니다. 좋은 강의 정말 감사합니다. ^^
      • 조신부리
        감사합니다
      • Sirhc
        사소한 거지만.. 오타

        예제가 복잡해보이지만 "한나씩" 분해해서 생각해보면 어렵지 않다.
      • egoing
        아래 링크에서 이에 대한 본격적인 내용이 나오게 됩니다.

        http://opentutorials.org......571
        대화보기
        • 망고레
          강의 잘 보았습니다. 간단명료하게 설명하시는게 인상적이네요.
          강의를 보다가 궁금한점이 생기는데요...

          같은 결과를 아래와 같이 하게 되면 좀 더 직관적일 수 있을텐데, 아래 방식에 대비해서 apply를 쓰는 장점이 뭐가 있을런지요? 또는 프로그래밍중에 꼭 apply를 써야되는 경우가 있다면 소개 좀 부탁드립니다.

          function sum (targetObj) {
          var prop = "";
          var _sum = 0;
          for (prop in targetObj){
          _sum += targetObj [prop];
          }
          return _sum;
          }

          sum 함수안에 this를 쓴다면, 이 this가 어떤 타입의 object에 맞는것인지 모호하지만,
          targetObj나 기타 명시적인 변수 이름을 사용하면 이게 더 코드를 보기 쉽게 하지 않을까 해서요.
        • 나무마루
          this 굉장히 흥미롭군요.
        • 도로시
          100% 이해하지는 못했지만 재밌는 내용이네요 ^^
          좋은 강의 감사합니다!
        • bara
          시즌 2에 와서는 봤어요를 정말 문자그대로 "봤어요"를 누르는 일이 다반사군요. 어렵네요.
        • somdari
          JavaScript에서 함수는 독립적인 객체로서 존재한다는 것도 재미있는데, apply 메소드를 통해 런타임시에는 다른 객체의 소유물인 것처럼 실 행 할 수 있다니.. 정말 흥미롭네요.. 동영상에서 apply 메소드를 왜 사용하는지 설명하기 위해 apply메소드를 사용하지 않고 같은 결과를 코드로 보여주는 대목이 참 좋았습니다..^^;
        버전 관리
        egoing
        현재 버전
        선택 버전
        graphittie 자세히 보기