본문 바로가기
javaScript

javaScript - 함수

by sinabeuro 2021. 7. 16.
728x90

1. 자바스크립트의 함수 호출 3가지 방식

  • 함수명으로 호출 
function myFn() {
	return 100;
}

const result = myFn();

myFn 함수를 myFn() 과 같이 함수명으로 호출합니다.

특이한 점은 자바스크립트는 함수를 변수로 취급한다는 것입니다.

그래서 const result = myFn(); 와 같이 호출하면 result 변수에 함수값이 저장됩니다.

즉, 변수에 함수를 넣는 것입니다.

뒤에 살펴볼 익명함수는 반드시 변수에 넣어야지 사용할 수 있습니다.

위의 코드는 함수 정의문으로 함수를 구현했습니다.

반면

 

const myFn2 = function () {
	return 100;
}

myFn2();

위의 함수는 함수 정의식으로 함수를 구현했습니다.
함수 정의문과 함수 정의식의 차이점은 함수 정의식은 뒤에 세미콜론(;)을 찍는 것이 원칙입니다. 

식 뒤에는 세미콜론을 붙여야하는 것이죠. 하지만 굳이 안 붙여도 오류가 발생하지 않습니다.

또 다른 차이점으로는 함수 정의식은 객체변수의 프로퍼티에 저장해서 호출할 수 있다는 점입니다.

예를 들면 test.callFn 과 같이 변수명을 사용하는 것으로 함수 정의식의 함수를 호출할 수 있습니다.

 

 

  • call 메소드를 이용한 함수 호출

call 메소드를 이용한 함수 호출을 살펴보기 전에 argments 개념을 먼저 살펴 보겠습니다.

function sum(a, b, c) {
  return a + b + c;
}

console.log(sum());		// NaN
console.log(sum(10));		// NaN
console.log(sum(10, 20));	// NaN
console.log(sum(10, 20, 30));	// 60

자바스크립트는 인자의 수와 상관없이 호출되는 것을 알 수 있습니다.

호출은 되지만 정의한 인자값에 값이 없으면 undefined가 되며 함수 결과값은 NaN(Not-A-Number)가 됩니다.

인자 기술 없이도 함수가 호출되므로 이러한 것을 방지하기 위해 argments 속성을 이용해서 함수를 정의할 수 있습니다.

function sum(a, b, c) {
  let s = 0;
  console.log(arguments);
  for(let i=0; i < arguments.length; i++) {
      s = s + arguments[i];
  }
  return s;
}

console.log(sum());		// 0
console.log(sum(10));		// 10
console.log(sum(10, 20));	// 30
console.log(sum(10, 20, 30));	// 60

argments는 함수가 정의한 인자 값과 상관 없이 호출 시 입력된 모든 파라미터를 배열 형식으로 저장합니다.

sum()의 arguments는 [] 입니다.

sum(10)의 arguments는 [10] 입니다.

sum(10, 20)의 arguments는 [10, 20] 입니다.

sum(10, 20, 30)의 arguments는 [10, 20, 30] 입니다.

 

그렇다면 함수정의 인자에 인자를 기술할 필요가 없을까요?

여기서 가변인자 개념을 아시면 좋을 것 같습니다.

rest Parameter(전개 파라미터)를 이용해서 재함수를 정의해보겠습니다.

function sum(...args) {
  let s = 0;
  console.log(arguments);
  for(let i=0; i < arguments.length; i++) {
      s = s + arguments[i];
  }
  return s;
}

rest Parameter의 표현 방식을 ...args과 같이 ...을 이용하여 인자명을 기술하면 됩니다.

rest Parameter는 함수 시그니처에 최대한 많은 정보를 기술하기 사용됩니다.

참고로 고정 변수, 가변 변수를 구분하고 싶은 경우에는 function sum(a, b, ...args) { ... }; 와 같은 방식으로 정의하면 됩니다.  이 경우 console.log(args)를 출력 시 가변 변수만 args 값에 배열형식으로 저장됩니다.

 

이제 본론으로 돌아와서 call 메소드를 이용해서 함수를 호출하겠습니다.

sum.call(null, 10, 20, 30); 형식으로 sum함수를 호출할 수 있습니다. 

다만 첫 인자는 context를 넘겨주고 두번째부터 함수 호출의 파라미터를 콤마로 구분해서 호출하면 됩니다.

다음 설명할 apply 메소드를 이용한 함수 호출 방식과 비교해보겠습니다.

 

  • apply 메소드를 이용한 함수 호출

apply 메소드는 함수 호출 시 필요한 파라미터들을 배열로 받습니다.

sum.apply(null, [10, 20, 30]);

sum.apply(null, [10, 20, 30])와 sum.call(null, 10, 20, 30)의 결과값은 같습니다.

그렇다면 어떨 때 call과 apply를 쓰는 것일까요?

두 방식의 공통점은 둘 다 context를 사용하며 첫 인자로 context를 전달합니다.

다만 파라미터가 기술 방식의 차이가 있습니다.

apply 메소드는 함수 인자를 배열방식으로 넘기기 때문에 외부에서 파라미터를 공급받을 때 사용하기 좋다.

예를 들면

var arr = [10, 20, 30];
sum.apply(null, arr);

이와 같은 방식으로 사용하기 좋습니다.

 

 

2. 무명함수 - 즉시 실행함수

const myFn2 = function () {
	return 100;
}

myFn2();

앞서 설명한 함수 정의식으로 변수에 값을 저장하는 방식이 무명함수입니다.

 

무명함수의 응용버전인 즉시 실행 함수를 보겠습니다.

(function() {
	console.log('즉시 실행 함수 실행!');
})();

즉시 실행 함수는 함수를 괄호로 묶고 괄호로 호출하는 방식으로 사용합니다.
즉시 실행 함수는 실행하는 순간 값을 만들고 끝나며, 어플리케이션 내에서 단 한번만 실행됩니다.

재호출이 불가능합니다.

 

3. 화살표 함수(arrow 함수)

const ten = (x) => return 100 + x;

const ten = x => 100 + x;

위의 예는 동일한 화살표 함수입니다.
인자가 하나일 때 인자의 괄호 생략가능 하며, 코드가 두줄 이상이면 브래이스{}와 return을 생략할 수 없습니다.

화살표 함수는 코드를 간략하게 표현하고 가독성을 높이기 위해서 사용합니다.

자세한 내용은 시간나면 다시 다루어보도록 하겠습니다.

 

4. 생성기 함수(generator 함수)

generator 함수는 통상적인 함수의 작동 방식과는 완전히 다릅니다.
최초 실행 시 실행되지 않고 실행 준비 상태로만 만듭니다.
그리고 객체 하나를 반환하는데 준비상태를 마친 함수를 실행할 도구를 담은 객체를 반환합니다.
그 도구를 이용해서 함수를 실행했다가 멈췄다가를 할 수 있게 만드는 것이 generator 함수입니다.

function* gen() {
	// 밖으로 return하는 키워드 yield. return도 쓸 수 있긴함.
	yield 10;
    yield 20;
    yield 30;
}

const g = gen();	// generator 함수 준비
console.log(g.next());	// {value: 10, done: false}
console.log(g.next());	// {value: 20, done: false}
console.log(g.next());	// {value: 30, done: false}

인스턴스를 생성하는 것으로 generator 함수가 실행 준비 상태가 됩니다. 

꼭 인스트턴스를 생성하고 변수에 저장해야 함수의 다음 값들이 정상적으로 출력됩니다.

생성한 인스턴스의 next() 메소드를 이용해서 순차적으로 generator 함수의 값들이 출력됩니다.

 

5. 비동기 함수

비동기 함수는 이전에 다룬 글을 참조하면 좋을 것 같습니다.

https://getthismoment.tistory.com/25
https://getthismoment.tistory.com/26


 

728x90

댓글