JS에서의 함수

함수는 한 번 정의하면 몇 번이고 호출할 수 있는 코드 블록

<aside> 📌 클로저(Closure)란 프로그래밍 언어에서 중요한 개념으로, 함수 객체와 스코프를 조합한 것을 의미한다.

여기서 렉시컬 스코프를 구현하기 위해서는 함수 객체의 내부 상태에 함수의 코드 뿐만 아니라 함수가 정의된 스코프에 대한 참조도 반드시 포함되어 있어야 한다.

클로저의 주요 특징은

등이 있다.

</aside>

함수 정의

자바스크립트 함수를 정의하는 가장 단순한 방법은 function 키워드를 사용하는 것이다.

이런 함수를 선언적 함수라고 한다.

function distance(x1, y1, x2, y2) {
	let dx = x2 - x1;
	let dy = y2 - y1;
	return Math.sqrt(dx*dx + dy*dy);
}

함수에 이름을 붙이지 않을 수도 있다. 이를 익명 함수라고 하며, 람다라고도 한다.

const 함수 = function() {
    console.log('함수 내부의 코드입니다...1')
    console.log('함수 내부의 코드입니다...2')
    console.log('함수 내부의 코드입니다...3')
    console.log('')
}

다음과 같이 함수를 정의하는 것을 함수 표현식이라고 하는데, 위와 같은 방법 말고도 여러가지로 사용할 수 있다.

// 함수를 변수에 할당
const square = function(x) { return x*x; };

// 함수 표현식에도 이름을 쓸 수 있으며 재귀 호출에 유용
const f = function fact(x) { if (x <= 1) return 1; else return x*fact(x-1); };

// 함수 표현식을 다른 함수의 인자로 사용
[3, 2, 1].sort(function(a, b) { return a+b; });

// 함수 표현식을 정의하는 즉시 호출
let tensquared = (function(x) { return x*x; }(10));

<aside> 📌 **선언적 함수와 표현식으로 생성한 함수의 차이점

선언 형태**를 사용하면 함수 객체는 자신을 포함하는 코드가 실행되기 전에 존재하며, 코드 상에서 함수 정의 전의 위치에서도 호출 가능하다.

그러나 표현식으로 정의된 함수는 이렇게 동작하지 않는다. 함수를 정의하는 표현식이 실제로 평가되기 전에는 함수가 존재하지 않으며, 변수에 할당하기 전에는 참조할 수 없으므로 표현식으로 정의된 함수는 **정의하기 전에 호출할 수 없다.

익명 함수**는 순차적인 코드 실행에서 코드가 해당 줄을 읽을 때 생성되고, 선언적 함수는 입력한 순서대로 생성되고 같은 이름이라면 덮어 쓰므로,

익명 함수는 우리가 코드를 읽을 때와 같은 순서로 함수가 선언되지만, 선언적 함수는 코드를 읽는 순서와 반대로 함수가 선언되므로, 안전하게 사용할 수 있는 익명 함수가 더 선호된다.

같은 이유로 블록이 다른 경우에 선언적 함수의 이름이 같을 때, 실행 흐름을 예측하기가 힘들다.

</aside>

ES6 이후로는 화살표 함수라는 간결한 문법으로 함수를 정의할 수 있다.