함수란 명확한 목적에 의해 입력받은 값을 설계된 프로세스를 거쳐 가공, 저장, 할당, 전달하기 위한 코드의 기능적 집합이라고 할 수 있다. 같은 작업을 몇 번이고 반복할 수 있으며, 조금만 고쳐서 재활용할 수도 있다.
함수의 기능을 비유하는 많은 예시가 있지만, 음료를 포장하는 기계를 함수에 비유해서 생각해보자.
packaging이라는 이름의 이 기계는 재료(병, 음료, 뚜껑, 라벨)를 받아 기계 내부의 프로세스를 거쳐 완성된 음료병을 반환한다.
이 과정을 자바스크립트의 함수 선언식(Function Declaration)으로 도식화하면 아래와 같다.
function
키워드는 packaging이란 이름 앞에 붙어 이것이 함수임을 설명하고, 매개 변수(Parameters
)는 투입될 재료의 목록, 중괄호{ ... }
속의 코드 블럭은 입력된 값이 설계된 방식대로 가공되는 일련의 프로세스이며, 완제품은 return value
라고 할 수 있다.
일일히 하드코딩 하는 것을 가내수공업이라고 친다면 함수의 도입은 가히 산업혁명이라고 할 만 하다.
예를 들어 아래 사람의 이름을 입력하면 인삿말을 출력하는 간단한 Greeting 함수를 본다면
function greeting(firstName, lastName) {
return `Hey ${firstName} ${lastName}!, Pleased to meet you.`;
}
greeting('Wonkook', 'Lee');
// "Hey Wonkook Lee!, Pleased to meet you."
이름만 인자로 전달하여 함수를 호출하면 간단히 인삿말이 완성되어 반환된다.
함수만 호출하면 몇 만번이고 계속 사용할 수 있는 강력한 도구가 되었다.
함수의 정의(Define)를 비유한다면 위와 같이 설계도, 명세서에 의해 기계를 만드는 것이 될 수 있고, 함수를 호출(Invoke or Call) 하는 것은 완성된 기계에 재료를 투입하여 실제로 작동시키는 행위에 비유할 수 있다. 함수를 호출하는 단계에서 전달되는 재료는 매개 변수(Parameters
)가 아닌 인자(Arguments
)라고 표현한다. 함수의 용도에 따라 매개 변수는 생략되어도 상관없다.
함수를 정의할 때 | 함수를 호출할 때 |
---|---|
매개 변수 (Parameters) | 인자 (Arguments) |
함수 내부에서만 유효한 placeholder | 실질적인 값 (데이터 타입) |
함수를 정의하는 방법은 많다. 함수를 만든다는 맥락은 같지만 함수는 정의하는 방법에 따라 다른 특성을 가진다.
// Syntax
function 함수명(매개변수) {
코드블럭
}
// 함수 선언식 (함수 정의)
function calcSum(num1, num2) {
return num1 + num2;
}
// 함수 호출 (실행)
calcSum(5, 8);
// expected output: 13
위와 같이 function
키워드에 이어 함수명을 붙여 함수를 정의하는 방법을 함수 선언식이라고 한다. 함수 표현식과 달리 함수명을 지정하기 때문에 기명 함수라고도 한다.
함수 선언식은 var
키워드와 같이 호이스팅(Hoisting)되는 특성을 가진다.
calcAverage(3, 5);
// expected output: 4
function calcAverage(num1, num2) {
return (num1 + num2) / 2;
}
함수의 정의가 호이스팅되어 함수를 선언하기도 전에 함수의 참조, 호출이 가능하다.
함수 선언식의 이런 특징은 가독성, 유지 보수의 용이함을 저해하기 때문에 함수 선언식 대신 함수 표현식을 사용할 것을 권장하는 추세이다.
// Syntax
const 변수명 = function(매개변수) {
코드블럭
};
// 함수 표현식 (함수 정의)
const calcAverage = function(num1, num2) {
return (num1 + num2) / 2;
};
// 함수 호출 (실행)
calcAverage(5, 7);
// expected output: 6
함수 표현식은 가장 많이 사용되는 함수 정의 방식이다. 변수에 함수의 참조값을 할당하여 함수 자체를 다른 함수의 인자로 사용할 수 있으며, 호이스팅의 영향을 받지 않는 장점이 있다.
변수를 선언하는 것과 똑같이 var
, let
, const
키워드를 사용하여 함수 표현식을 만들 수 있다.
그러나 이것은 함수의 이름은 아니고 함수가 실질적으로 저장된 주소값을 참조하는 변수명이다. 그래서 함수의 이름이 없기 때문에 함수 표현식으로 정의된 함수를 익명 함수(Anonymous Function)이라고도 한다.
// 화살표 함수 (ES6)
const 변수명 = (매개변수) => {
코드블럭
};
화살표 함수는 ES6 이후 소개된 새로운 함수 정의 방식이다.
할당 연산자(=)까진 함수 표현식과 같고, 매개 변수( )
와 코드 블럭 { ... }
사이에 =>
화살표 표시를 넣음으로써 function
키워드와 같은 역할을 한다.
사용하는 방법에 따라 가독성이 좋고, 간편하며, 코드가 짧아지는 장점이 있다. 매개 변수가 한개라면 소괄호 없이 아래와 같이 작성할 수 있다.
const americano = espresso => return espresso + hotWater;
하지만 화살표 함수는 this
와 arguments
프로퍼티, prototype
이 없기 때문에 사용하지 말아야 할 경우가 생긴다.
예를 들어 객체 안에서 this
로써 해당 객체를 참조하는 메소드 함수의 경우, 화살표 함수의 this
는 참조값이 Window
객체가 되기 때문에 참조 오류가 나게된다.
const person = {
firstName: 'Wonkook',
birthYear: 1990,
calcAge: function() { // 프로퍼티 함수 (메소드)
return 2021 - this.birthYear;
}
};
person.calcAge();
// expected output: 31
객체(Object) 내부에 내장된 함수를 메소드 함수 또는 메소드라고 부른다.
생성자, 클래스에 메소드를 만들수도 있고 인스턴스 객체에도 메소드를 넣을 수 있다. 이는 객체 지향 프로그래밍(OOP)의 일환으로 설명이 가능하겠다.
흔히 쓰는 배열 관련 함수도 메소드라고 부르며, 배열의 원형(Array.prototype)의 내장 함수이기 때문에 그렇게 부른다.
함수를 실행하는 것을 함수를 '호출'한다고 표현한다.
함수를 호출하는 방법은 함수명, 또는 함수가 저장된 변수명 뒤에 괄호를 붙이는 것이다.
// Invoke
doSomething();
함수가 매개 변수를 받는다면 괄호 안에 해당 인자를 넣어주면 된다.
배열과 객체도 인자로 전달될 수 있으며, 심지어 함수도 인자로 전달될 수 있다. (콜백 함수 등)
// Invoke with arguments
doSomething(arg1, arg2, ...);
// Passing an array as an argument
doSomething2([arg1, arg2, arg3, ...]);
// Function as an argument
Element.addEventListener('click', doSomething3);
const doSomething = function() {
return something; // 함수 호출시 함수가 종료되는 지점
};
함수는 결과값을 반환(return
)하는 즉시 종료된다. 함수가 의도치 않게 종료되지 않도록 return
의 위치를 신중하게 정하는 것이 중요하다.
return
키워드를 생략한다면 함수는 결과를 산출하지 않고, 계산만 한 채 끝나게 된다.
화살표 함수의 경우 표현식이 한 줄로 끝나거나, 단순할 경우 return
키워드를 생략할 수 있다.
const multiplyByTwo = num => num * 2;
multiplyByTwo(8);
// expected output: 16
글과 이미지
Wonkook Lee ⓒ All Rights Reserved
🙏🏻 잘못된 정보가 있다면 지적해주세요