함수

2019. 7. 18. 14:26javascript

함수의 정의

함수를 생성하는 방식에는 3가지 방식이 있다. 각각의 방식에 따라 동작에 미묘한 차이가 있다.

  1. 함수 선언문 (function statement)
  2. 함수 표현식 (function expression)
  3. Function() 생성자 함수

1. 함수 리터럴

자바스크립트에서는 함수도 일반 객체처럼 값으로 취급된다. 때문에 함수 리터럴을 이용해 함수를 생성할 수 있다, 

함수 선언문이나 함수 표현식 모두 이런 방식으로 함수를 생성한다.

function add (x,y) {
	return x+y
}

함수 리터럴은 크게 네 부분으로 구성되어 있다 

  1. function 키워드 
  2. 함수명 : 함수명을 통해서 재귀적으로 호출하거나 디버거가 함수를 구별하는 식별자로 사용된다. 자바스크립트에서 함수명은 선택 사항으로 함수명이 없는 함수를 익명 함수라고 한다.
  3. 매개변수 리스트
  4. 함수 몸체 

2. 함수 선언문

함수 선언문은 함수 리터럴 형태와 같다. 단 함수 선언문 방식으로 정의된 함수는 반드시 함수명이 정의되어 있어야 한다. 

 

function add(x,y){
	return x+y;
}

console.log(3,4) // 7

3. 함수 표현식

함수도 하나의 값처럼 취급되기 때문에 변수에 할당하는 것이 가능하다. 이런 방식으로 함수 리터럴 방식으로 함수를 만들고 이것을 변수에 할당하여 함수를 만드는 것을 함수 표현식이라고 말한다.

var add = function(x,y){
	return x+y;
};

var plus = add;

console.log(add(3,4)); // 7
console.log(plus(5,6)); // 11

여기서 생성된 함수는 이름이 없으므로 익명 함수이다.

plus 또한 add의 함수를 참조하기 때문에 함수를 호출하는 것이 가능하다. (두 변수가 같은 익명 함수를 참도 하는 형태)

add 변수 익명함수 
plus 변수

이름이 포함된 함수 표현식을 기명 함수 표현식이라고 한다. 이를 사용할 때는 주의해야 할 점이 있다.

var add = function sum(x,y) {
	return x+y;
};    

console.log(add(3,4)); // 7
console.log(sum(3,4)); // Uncaught ReferenceError: sum is not defined

함수 선언문 형식으로 정의한 add()함수는 자바스크립트 엔진에 의해 다음과 같은 형태로 변경되기 때문에 이런 에러가 발생한다.

var add= function add(x, y){
	return x+y;
};

앞서 말했듯이 함수 이름을 이용하면 함수 코드 내부에서 함수 이름으로 재귀적인 호출이 가능하다.

 

※function statement 와 function expression에서의 세미콜론

일반적으로 자바스크립트 코드를 작성할 때 함수 선언문 방식으로 선언된 함수는 세미콜론을 붙이지 않지만 

함수 표현식 장식의 경우 세미콜론을 붙이는 것을 권장한다. 

var func = function() {
	return 42;
} // 세미콜론 사용하지 않음
(function)() {
	console.log("function called");
})(); 

console.log(func()); // "number is not a function"

이 코드는 43를 리턴하는 함수 func()를 정의하고, 즉시 실행 함수 형식으로 "function called"를 출력하려고 했지만 에러가 발생한다.

세미콜론을 사용하지 않아서 func() 함수가 끝났지만 끝났다고 판단하지 않고 즉시 실행 함수 보고 func() 함수 호출로 생각하여 호출해 버린다. 

 

func() 실행 => 42 반환 즉시 실행 함수 실행 => 42();

 

즉 위와 같은 형태가 되어 42는 함수가 아니므로 "number is nat a function" 에러가 발생하는 것이다.

 

4. Function() 생성자 함수를 통한 함수 생성하기 

일반적으로 자주 사용되는 방식이 아니기 떄문에 알아만 두면 될 것 같다.

var add = new Function("x", "y", "return x+y");
console.log(add(3,4)); // 7

5. 함수 호이스팅

add(2,3); // 5

//함수 선언문
function add(x, y) {
	return x+y;
}

add(3,4) // 7

처음 add 함수를 호출할 때 함수가 정의 되지 않은 상태 인데도 실행이 되고 있다. 함수 선언문 형태로 정의한 함수의 유효 범위는 코드의 맨 처음부터 시작 한다는 것을 확인할 수 있다. 

 

add(2,3); // uncaught type error

//함수 표현식 형태로 add() 함수 정의
var add = function (x,y) {
	return x+y;
};

add(3,4) // 7

함수 표현식 형태로 정의되어 있어 호이스팅이 일어나지 않는다. 함수가 생성된 뒤 부터 호출이 가능하다. 

 

이러한 이유는 변수 생성(instantiation)초기화(initialization)의 작업이 분리되어 있기 때문이다.

'javascript' 카테고리의 다른 글

Prototype, __proto__, constructor 의 관계  (0) 2019.07.29
함수 객체  (0) 2019.07.19
배열  (0) 2019.07.17
객체  (0) 2019.07.15
자바스크립트 데이터 타입  (0) 2019.07.14