index
② 함수의 종류
2.1 함수 선언문
2.2 함수 표현식
2.3 Function 생성자 함수
2.4 화살표 함수
2.5 즉시 실행 함수
2.6 재귀 함수
2.7 중첩 함수
2.8 콜백 함수
1. 함수(Function)의 정의

DefinitionofFunction
Jay Tak.
변수선언과 함수정의 용어 명료화! 반드시 필요한 과정
변수는 ‘선언(declaration)’한다고 했지만 함수는 ‘정의(definition)’한다고 표현한다. 함수선언문이 평가되면 식별자가 암묵적으로 생성되고 함수 객체가 할당된다. ECMAScript 사양에서도 변수에는 선언(declaration), 함수에는 정의(definition)라고 표현한다.
🧐 Q. 함수는 왜 사용할까?
-
코드의 재사용
동일한 작업을 반복적으로 수행해야 한다면 같은 코드를 중복해서 여러번 작성하는 것이 아니라 미리 정의된 함수를 재사용하는 것이 효율적
-
유지보수의 편의성 및 코드의 신뢰성
같은 코드를 중복해서 여러 번 작성하면 코드를 수정해야 할 때 중복된 횟수만큼 수정해야 한다. 코드의 중복을 억제하고 재사용을 높일 수 있다.
-
코드의 가독성
함수는 객체 타입으로 이름(식별자)를 붙일 수 있다. 이는 함수 코드를 이해하지 않고도 함수의 역할을 파악할 수 있게 돕는다.
2. 함수의 종류
2.1 함수 선언문
• 함수선언문은 함수 이름을 생략할 수 없다.
함수는 함수이름으로 호출하는 것이 아니라 함수 객체를 가르키는 식별자로 호출한다. 그림 (함수정의 그림 p.162)
• 함수선언문은 표현식이 아닌 문이다.
function add(x, y) {
return x + y;
}
🧐 Q. 함수리터럴을 변수에 할당할 경우, 함수 리터럴 표현식으로 생성된 bar는 호출 할 수 있을까?
// 1. 기명 함수 리터럴
function foo() {}
// 2. 기명 함수 표현식
const foo = function bar() {};

DeclarationOfFunction
Jay Tak.
2.2 함수 표현식
let add = function (x, y) {
return x + y;
};
2.3 function 생성자 함수
Function 생성자 함수로 함수를 생성하는 방식은 일반적이지 않으며 바람직하지 않다. Function 생성자 함수로 생성한 함수는 클로저를 생성하지 않는 등, 함수선언문이나 함수표현식으로 생성한 ㅎ마수와 다르게 동작한다.
let add1 = (function () {
let a = 10;
return function (x, y) {
return x + y + a;
};
})();
console.log(add1(1, 2)); // 13
let add2 = (function () {
let a = 10;
return new Function("x", "y", "return x + y + a;");
})();
console.log(add2(1, 2)); // ReferenceError: a is not defined
2.4 화살표 함수
const add = (x, y) => x + y;
console.log(add(2, 3)); // 5
2.5 즉시실행함수
(function () {
let a = 3;
let b = 5;
return a * b;
})();
2.6 재귀함수
function countdown(n) {
for (let i = n; i >= 0; i--) console.log(i);
}
countdown(10);
2.7 중첩함수
function outer() {
let x = 1;
function inner() {
let y = 2;
console.log(x + y);
}
inner();
}
outer();
2.8 콜백함수
function reneat(n, f) {
for (let i = 0; i < n; i++) {
f(i);
}
}
let logAll = function () {
console.log(i);
};
repeat(5, logAll); // 0 1 2 3 4
3. 함수 생성시점과 함수호이스팅
함수선언문과 함수표현식을 엔진이 이해하는 방식에 있어서의 차이
// 1. 함수 선언문(function Declaration)
sayHello() // "Hello"
function sayHello() {
console.log("Hello");
}
🤓 호이스팅:
- 함수 선언문으로 정의된 함수는 스코프의 최상단으로 호이스팅 됨
- 이는 함수가 정의되기 전에 호출 될 수 있다는 의미이다. 즉, 코드가 실행되기 전에 함수가 메모리에 로드된다.
// 2. 함수 표현식(function Declaration)
sayHello() // TypeError: sayHello is not a function
consst sayHello = function() {
console.log("Hello");
};
🤓 호이스팅:
- 함수 표현식 자체는 호이스팅되지 않지만, 함수가 할당된 변수는 호이스팅됩니다.
- 변수 자체는 호이스팅 되지만, 초기화는 실제 코드가 실행시점에 이루어지므로 변수에 할당된 함수는 정의되기 전에 호출할 수 없다
🧐 Q. Function 생성자 함수가 클로저를 생성하지 않는 이유는 무엇인가?
let add1 = (function () {
let a = 10;
return function (x, y) {
return x + y + a;
};
})();
console.log(add1(1, 2)); // 13
let add2 = (function () {
let a = 10;
return new Function("x", "y", "return x + y");
})();
console.log(add2(1, 2)); // ReferenceError: a is not defined
Function 생성자는 함수를 생성할 때 그 함수의 렉시컬 환경(lexical environment)을 현재의 스코프가 아닌 전역 스코프에서 생성한다. 이는 Function 생성자가 항상 전역 스코프를 참조하기 때문에 클로저가 생성되지 않는다.
4. 참조에 의한 전달과 외부 상태의 변경
원시 값은 ‘값에 의한 전달(pass by Value)’
객체는 ‘참조에 의한 전달(pass by Reference)’방식으로 동작한다.
🧐 Q. 매개변수로 원시값과 객체를 전달해서 함수몸체에서 변경한다면 원시값과 객체는 어떤 변화가 있을까?
let num = 100;
let person = {name: 'Kim'};
function changeVal(primitive, obj) {
primitive = 200;
obj.name = 'Lee'
return {primitive, name: obj.name};
}
console.log(changeVal(num, person)); => { primitive: 200, name: 'Lee' }
console.log(num); => 100
console.log(person); => { name: 'Lee' }
그림 (함수정의 그림 p.176)
원시 값은 변경 불가능한 값(immutable value)이므로,
직접 변경할 수 없기 때문에 재할당을 통해 원시값을 새로운 원시값으로 교체했고,
객체는 변경 가능한 값(mutable value)이므로,
직접 변경할 수 있기 때문에 재할당 없이 직접 할당된 객체를 변경한다.
5. 순수함수와 비순수함수
함수형 프로그래밍에서는 어떤 외부 상태에 의존하지도 않고 변경하지도 않는, 즉 부수 효과가 없는 함수를 순수함수(pure function)라 하고, 외부상태에 의존하거나 외부상태를 변경하는, 즉 부수효과가 있는 함수를 비순수함수(impure function)라고 한다.
let count = 0; // 현재 카운트를 나타내는 상태
// 순수함수, increase는 동일한 인수가 전달되면 언제나 동일한 값을 반환한다.
function increase(n) {
return ++n;
}
// 순수함수가 반환한 결과값을 변수에 재할당해서 상태를 변경
count = increase(count);
console.log(count); // 1
count = increase(count);
console.log(count); // 2
let count = 0; // 현재 카운트를 나타내는 상태: increase 함수에 의해 변화한다.
// 비순수 함수
function increase() {
return ++count;
}
// 비순수 함수는 외부상태(count)를 변경하므로 상태 변화를 추적하기 어려워진다.
increase();
console.log(count); // 1
increase();
console.log(count); // 2
순수 함수는 동일한 인수가 전달되면 언제나 동일한 값을 반환하는 함수다. 즉 순수함수는 어떤 외부 상태에도 의존하지 않고 오직 매개변수를 통해 함수 내부로 전달되 인수에게만 의존해 값을 생성해 반환한다.