자바스크립트의 함수


1. 함수 (Functions)


1-1. 함수란?

함수란 명확한 목적에 의해 입력받은 값을 설계된 프로세스를 거쳐 가공, 저장, 할당, 전달하기 위한 코드의 기능적 집합이라고 할 수 있다. 같은 작업을 몇 번이고 반복할 수 있으며, 조금만 고쳐서 재활용할 수도 있다.

함수의 기능을 비유하는 많은 예시가 있지만, 음료를 포장하는 기계를 함수에 비유해서 생각해보자.


1-2. 함수의 구성

packaging이라는 이름의 이 기계는 재료(병, 음료, 뚜껑, 라벨)를 받아 기계 내부의 프로세스를 거쳐 완성된 음료병을 반환한다.

이 과정을 자바스크립트의 함수 선언식(Function Declaration)으로 도식화하면 아래와 같다.


function 키워드는 packaging이란 이름 앞에 붙어 이것이 함수임을 설명하고, 매개 변수(Parameters)는 투입될 재료의 목록, 중괄호{ ... }속의 코드 블럭은 입력된 값이 설계된 방식대로 가공되는 일련의 프로세스이며, 완제품은 return value라고 할 수 있다.

1-3. 함수의 필요성

일일히 하드코딩 하는 것을 가내수공업이라고 친다면 함수의 도입은 가히 산업혁명이라고 할 만 하다.
예를 들어 아래 사람의 이름을 입력하면 인삿말을 출력하는 간단한 Greeting 함수를 본다면

function greeting(firstName, lastName) {
  return `Hey ${firstName} ${lastName}!, Pleased to meet you.`;
}

greeting('Wonkook', 'Lee');
// "Hey Wonkook Lee!, Pleased to meet you."

이름만 인자로 전달하여 함수를 호출하면 간단히 인삿말이 완성되어 반환된다.
함수만 호출하면 몇 만번이고 계속 사용할 수 있는 강력한 도구가 되었다.



2. 함수의 정의와 호출


함수의 정의(Define)를 비유한다면 위와 같이 설계도, 명세서에 의해 기계를 만드는 것이 될 수 있고, 함수를 호출(Invoke or Call) 하는 것은 완성된 기계에 재료를 투입하여 실제로 작동시키는 행위에 비유할 수 있다. 함수를 호출하는 단계에서 전달되는 재료는 매개 변수(Parameters)가 아닌 인자(Arguments)라고 표현한다. 함수의 용도에 따라 매개 변수는 생략되어도 상관없다.

함수를 정의할 때함수를 호출할 때
매개 변수 (Parameters)인자 (Arguments)
함수 내부에서만 유효한 placeholder실질적인 값 (데이터 타입)

함수를 정의하는 방법은 많다. 함수를 만든다는 맥락은 같지만 함수는 정의하는 방법에 따라 다른 특성을 가진다.

2-1. 함수 선언식 (Function Declaration)

// Syntax
function 함수명(매개변수) {
  코드블럭
}

// 함수 선언식 (함수 정의)
function calcSum(num1, num2) {
  return num1 + num2;
}

// 함수 호출 (실행)
calcSum(5, 8);
// expected output: 13

위와 같이 function 키워드에 이어 함수명을 붙여 함수를 정의하는 방법을 함수 선언식이라고 한다. 함수 표현식과 달리 함수명을 지정하기 때문에 기명 함수라고도 한다.
함수 선언식은 var 키워드와 같이 호이스팅(Hoisting)되는 특성을 가진다.

2-1-1. 함수 선언식의 호이스팅

calcAverage(3, 5);
// expected output: 4

function calcAverage(num1, num2) {
  return (num1 + num2) / 2;
}

함수의 정의가 호이스팅되어 함수를 선언하기도 전에 함수의 참조, 호출이 가능하다.
함수 선언식의 이런 특징은 가독성, 유지 보수의 용이함을 저해하기 때문에 함수 선언식 대신 함수 표현식을 사용할 것을 권장하는 추세이다.

2-2. 함수 표현식 (Function Expression)

// Syntax
const 변수명 = function(매개변수) {
 코드블럭
};

// 함수 표현식 (함수 정의)
const calcAverage = function(num1, num2) {
  return (num1 + num2) / 2;
};

// 함수 호출 (실행)
calcAverage(5, 7);
// expected output: 6

함수 표현식은 가장 많이 사용되는 함수 정의 방식이다. 변수에 함수의 참조값을 할당하여 함수 자체를 다른 함수의 인자로 사용할 수 있으며, 호이스팅의 영향을 받지 않는 장점이 있다.

변수를 선언하는 것과 똑같이 var, let, const 키워드를 사용하여 함수 표현식을 만들 수 있다.
그러나 이것은 함수의 이름은 아니고 함수가 실질적으로 저장된 주소값을 참조하는 변수명이다. 그래서 함수의 이름이 없기 때문에 함수 표현식으로 정의된 함수를 익명 함수(Anonymous Function)이라고도 한다.

2-3. 화살표 함수 (Arrow Function; ES6)

// 화살표 함수 (ES6)
const 변수명 = (매개변수) => {
 코드블럭
};

화살표 함수는 ES6 이후 소개된 새로운 함수 정의 방식이다.
할당 연산자(=)까진 함수 표현식과 같고, 매개 변수( )와 코드 블럭 { ... }사이에 => 화살표 표시를 넣음으로써 function 키워드와 같은 역할을 한다.

사용하는 방법에 따라 가독성이 좋고, 간편하며, 코드가 짧아지는 장점이 있다. 매개 변수가 한개라면 소괄호 없이 아래와 같이 작성할 수 있다.

const americano = espresso => return espresso + hotWater;

하지만 화살표 함수는 thisarguments프로퍼티, prototype이 없기 때문에 사용하지 말아야 할 경우가 생긴다.

예를 들어 객체 안에서 this로써 해당 객체를 참조하는 메소드 함수의 경우, 화살표 함수의 this는 참조값이 Window 객체가 되기 때문에 참조 오류가 나게된다.

2-4. 메소드 함수 (Methods)

const person = {
  firstName: 'Wonkook',
  birthYear: 1990,
  calcAge: function() { // 프로퍼티 함수 (메소드)
    return 2021 - this.birthYear;
  }
};

person.calcAge();
// expected output: 31

객체(Object) 내부에 내장된 함수를 메소드 함수 또는 메소드라고 부른다.
생성자, 클래스에 메소드를 만들수도 있고 인스턴스 객체에도 메소드를 넣을 수 있다. 이는 객체 지향 프로그래밍(OOP)의 일환으로 설명이 가능하겠다.

흔히 쓰는 배열 관련 함수도 메소드라고 부르며, 배열의 원형(Array.prototype)의 내장 함수이기 때문에 그렇게 부른다.

2-5. 함수의 호출 (Invoke Function)

함수를 실행하는 것을 함수를 '호출'한다고 표현한다.
함수를 호출하는 방법은 함수명, 또는 함수가 저장된 변수명 뒤에 괄호를 붙이는 것이다.

// 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);


3. 함수의 종료


3-1. return 키워드

const doSomething = function() {
  return something; // 함수 호출시 함수가 종료되는 지점
};

함수는 결과값을 반환(return)하는 즉시 종료된다. 함수가 의도치 않게 종료되지 않도록 return의 위치를 신중하게 정하는 것이 중요하다.
return 키워드를 생략한다면 함수는 결과를 산출하지 않고, 계산만 한 채 끝나게 된다.

3-2. 화살표 함수의 return 생략

화살표 함수의 경우 표현식이 한 줄로 끝나거나, 단순할 경우 return키워드를 생략할 수 있다.

const multiplyByTwo = num => num * 2;

multiplyByTwo(8);
// expected output: 16


글과 이미지
Wonkook Lee ⓒ All Rights Reserved

🙏🏻 잘못된 정보가 있다면 지적해주세요

profile
© 가치 지향 프론트엔드 개발자

0개의 댓글