- 일련의 과정을 문(statement)으로 구현하고 코드 블록으로 감싸서 하나의 실행 단위로 정의
- 함수는 함수 정의(function definition)를 통해 생성
function add(num1, num2) {
return num1 + num2;
}
- 코드의 재사용
- 유지보수의 편의성
- JS에서 함수는 객체 타입의 값
- 함수도 함수리터럴 생성 가능
- 함수 리터럴은 function 키워드, 함수 이름, 매개변수, 함수 몸체로 구성
// 변수에 함수 리터럴을 할당
var f = function add (num1, num2) {
return num1 + num2;
}
function add(num1, num2) {
return num1 + num2;
}
var add = function add(num1, num2) {
return num1 + num2;
}
console.log(add(1, 2));
console.log(sub(1, 2));
// 함수 선언문
function add(num1, num2) {
return num1 + num2;
}
// 함수 표현식
var sub = function(num1, num2) {
return num1 - num2;
}
// 결과
3
"Uncaught TypeError: sub is not a function"
함수 선언문은 정상 호출, 함수 표현식은 에러!
함수 선언문과 함수 표현식으로 생성된 함수의 생성 시점이 다르기 때문
함수 선언문의 경우 런타임 이전에 JS Engine에 의해서 먼저 실행(함수 호이스팅)
함수 표현식은 var 키워드를 사용한 변수 선언문과 동일하게 동작
var 키워드를 선언된 변수는 undefined로 초기화
이후 함수 표현식의 함수 리터럴도 할당문이 실행되는 시점에 평가
변수 호이스팅 발생
- 함수 호이스팅은 함수를 호출하기 전 반드시 함수를 선언해야 한다는 당연한 규칙을 무시한다. 이 때문에, JSON을 창안한 더글라스 크락포트는 함수 표현식을 사용할 것을 권장한다.
var add = new Function('num1', 'num2', 'return num1 + num2');
console.log(add(1, 2));
// 결과
3
const add = (num1, num2) => num1 + num2;
console.log(add(1, 2));
// 결과
3
함수명 대신 변수명에 함수 코드를 저장하는 구현 방식
화살표 함수는 기존의 함수 선언문 또는 함수 표현식을 완전히 대체 하는 것은 아니다.
기존의 함수보다 표현만 간략한 것이 아닌 내부 동작도 간략화되어 있기 때문이다.
function add(num1, num2) {
console.log(num1, num2);
return num1 + num2;
}
add(2, 5);
console.log(num1, num2);
// 결과
2, 5
"ReferenceError: num1 is not defined"
- 매개변수는 함수 내부에서만 참조할 수 있고 함수 외부에서는 참조할 수 없다. 즉, 매개변수의 스코프는 함수 내부이다.
function add(num1, num2) {
return num1 + num2;
}
console.log(add(1));
console.log(add(1, 2, 3));
// 결과
NaN
3
- 인수는 함수 내부에 암묵적으로 arguments 객체의 프로퍼티로 보관된다.
function add(num1, num2) { console.log(arguments); // Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ] return num1 + num2; } add(1, 2, 3);
function add(num1, num2) {
return num1 + num2;
}
console.log(add(1));
console.log(add("1", "2"));
// 결과
NaN
"12"
function add(num1, num2) {
if(typeof num1 !== "number" || typeof num2 !== "number") {
throw new TypeError("숫자 값이 아닌 인수가 존재합니다.");
}
return num1 + num2;
}
console.log(add(1));
console.log(add("1", "2"));
// 결과
"Uncaught TypeError: 숫자 값이 아닌 인수가 존재합니다."
// 기본값 매개변수
function add(num1 = 0, num2 = 0) {
return num1 + num2;
}
// 단축평가
function add(num1, num2) {
num1 = num1 || 0;
num2 = num2 || 0;
return num1 + num2;
}
function add(num) {
return num.num1 + num.num2 + num.num3 + num.num4;
}
var sum = add({
num4: 4,
num2: 2,
num3: 3,
num1: 1,
});
console.log(sum);
// 결과
10
- 매개 변수 순서를 신경 쓰지 않아도 되는 장점
- 함수 내부에서 객체를 변경하면 외부 객체도 변경되는 side effect 발생
- return 키워드에 표현식을 명시해주지 않으면 undefined로 평기
function func() { return; } console.log(func()); // 결과 undefined
function changeValue(primitive, object) {
primitive += 1;
object.name = "Kim";
}
var num = 1;
var person = { name: "Lee" };
console.log(num);
console.log(person);
console.log("---함수 호출---");
changeValue(num, person);
console.log(num);
console.log(person);
// 결과
1
{name: 'Lee'}
"---함수 호출---"
1
{name: 'Kim'}
(function () {
var num1 = 1;
var num2 = 2;
return num1 + num2;
}());
var sum = 0;
function add(n) {
if (n < 0) return;
sum += n;
add(n - 1);
}
add(5);
console.log(sum);
// 결과
15
function outer() {
var x = 1;
function inner() {
var y = 2;
console.log(x + y);
}
inner();
}
outer();
function allNumberPrint(n) {
for(var i = 1; i < n; i++) {
console.log(i);
}
}
function oddNumberPrint(n) {
for(var i = 1; i < n; i++) {
if(i % 2 !== 0) {
console.log(i);
}
}
}
allNumberPrint(5);
console.log("------");
oddNumberPrint(5);
// 결과
1
2
3
4
-----
1
3
function print(n, callback) {
for(var i = 1; i < n; i++) {
callback(i);
}
}
var allNumber = function (i) {
console.log(i);
}
var oddNumber = function (i) {
if(i % 2 !== 0) {
console.log(i);
}
}
print(5, allNumber);
console.log("------");
print(5, oddNumber);
// 결과
1
2
3
4
-----
1
3
document.getElementById("button").addEventListener("click", function () {
console.log("button click");
});
setTimeout(function () {
console.log("1초");
}, 1000);
var result = [1, 2, 3].map(function (item) {
return item * 2;
});
console.log(result);
var count = 0;
function increase(n) {
return ++n;
}
increase(count);
console.log(count);
// 순수 함수가 반환한 결과값을 변수에 재할당
count = increase(count);
console.log(count);
// 결과
0
1
var count = 0;
function increase(n) {
return ++count;
}
increase(count);
console.log(count);
count = increase(count);
console.log(count);
// 결과
1
2