4. 함수와 프로토타입 체이닝 #1 함수 정의

2021. 7. 22. 14:57JavaScript/basic

본 글은 인사이드 자바스크립트 도서의 내용을 복습하기 위해 작성된 글입니다.

4.1 함수 정의

함수 생성 방법

  1. 함수 선언문(function statement)
  2. 함수 표현식(function expression)
  3. Function() 생성자 함수

 

4.1.1 함수 리터럴

자바스크립트에서는 함수도 일반 객체처럼 값으로 취급한다. 따라서 객체 리터럴 방식처럼 자바스크립트에서는 함수 티러럴을 이용해 함수를 생성할 수 있다.

 

함수 리터럴을 통한 add() 함수 정의

function add(x,y){
	return x+y;
}
  1. function 키워드 : 자바스크립트 함수 리터럴은 function 키워드로 시작
  2. 함수명 : 함수의 이름, 함수명은 선택 사항이다. 함수명이 없는 함수를 익명 함수라 한다.
  3. 매개변수 리스트 : 함수의 인자들, 특징은 매개변수 타입이 존재하지 않는다.
  4. 함수 몸체 : 실제 함수가 호출됐을 때 실행되는 코드 부분

 

4.1.2 함수 선언문 방식으로 함수 생성하기

함수 선언문 방식은 앞에서 설명한 함수 리터럴 형태와 같다. 주의할 점은 함수 선언문 방식으로 정의된 함수의 경우는 반드시 함수명이 정의되어 있어야 한다.

 

add() 함수 생성(함수 선언문 방식)

// add() 함수 선언문
function add(x,y){
    return x+y;
}

console.log(add(3,4));  // 7

4.1.3 함수 표현식 방식으로 함수 생성하기

자바스크립에서는 함수도 하나의 값처럼 취급된다(이러한 자바스크립트의 함수는 일급 객체라고 한다). 따라서 함수도 숫자나 문자열처럼 변수에 할당하는 것이 가능하다.

 

함수 표현식 방식이란 무엇인가?

함수 리터럴로 하나의 함수를 만들고, 여기서 생성된 함수를 변수에 할당하여 함수를 생성하는 방식

 

add() 함수 생성(함수 표현식 방식)

// add() 함수 표현식
let add2 = function(x,y){
            return x+y;
        };

let plus = add2;

console.log(add2(3,4)); // 7
console.log(plus(3,4)); // 7

 

위의 코드에서 함수 변수 add가 실제로 참조하는 두 수를 더하는 함수의 이름이 없다. 이렇게 이름이 없는 함수 형태를 자바스크립트에서는 익명 함수(anonymouse function)라고 부른다. 이것이 바로 익명 함수를 이용한 함수 표현식 방법(익명 함수 표현식)이다.

 

기명 함수 표현식이란?

함수 표현식 방식에서 함수 이름이 포함된 함수 표현식을 기명 함수 표현식이라 한다.

 

기명 함수 표현식의 함수 호출 방법

let add = function sum(x,y){
    return x+y;
};

console.log(add(3,4));  // 7
console.log(sum(3,4));  // error

sum() 함수 호출의 경우 에러가 발생한다. 이것은 함수 표현식에서 사용된 함수 이름이 외부 코드에서 접근 불가능하기 때문이다.

 

기명 함수 표현식의 용도

정의된 함수 내부에서 해당 함수를 재귀적으로 호출하거나, 디버거 등에서 함수를 구분할때 사용된다.

 

함수 표현식 방식으로 구현한 팩토리얼 함수

let factorialVar = function factorial(n){
    if(n<=1)
    {
        return 1;
    }
    return n* factorial(n-1);
}

console.log(factorialVar(3)); // 6
console.log(factorial(3));  // Uncaught ReferenceError: factorial is not defined

함수명 factorial()으로 함수 외부에서 해당 함수를 호출하지 못해 에러가 발생한다.

 

팩토리얼값을 재귀적인 방식으로 구현한 함수 구조

4.1.4 Function() 생성자 함수를 통한 함수 생성하기

Function() 생성자 함수 문법

new Function (arg1, arg2, ... argN, functionBody)
- arg1, arg2, ... , argN : 함수의 매개변수
- functionBody - 함수가 호출될 때 실행될 코드를 포함한 문자열

Function() 생성자 함수를 이용한 add() 함수 생성

let add = new Function("x","y","return x + y");
console.log(add(3,4));  // 7

일반적으로 Function() 생성자 함수를 사용한 함수 생성 방법은 자주 사용되지 않는다.

 

4.1.5 함수 호이스팅

함수를 생성하는 방식 3가지(함수 리터럴, 함수 표현식, Function() 생성자 함수)는 코드는 약간씩 다르지만 모두 같은 기능의 함수를 생성함을 확인할 수 있다. 하지만 이들 사이에는 동작 방식이 약간 차이가 있다. 그중에 하나가 바로 함수 호이스팅(Function Hoisting)이다.

 

함수 선언문 방식과 함수 호이스팅

// 함수 선언문과 함수 호이스팅
// 아직 이 시점에 add()함수가 정의되지 않았음에도 정의된 add() 함수를 호출하는 것이 가능하다.
console.log(add(2,3)); // 5
function add(x,y){
    return x+y;
}

console.log(add(3,4));   // 7

console.log(add(2,3)) 시점에서는 add() 함수가 정의되지 않았음에도 아래 add() 함수를 호출하는 것이 가능하다. 이것은 함수가 자신이 위치한 코드에 상관없이 함수 선언문 형태로 정의한 함수의 유효 범위는 코드의 맨 처음부터 시작한다는 것을 확인할 수 있다. 이것을 함수 호이스팅이라고 부른다.

 

이러한 함수 호이스팅은 함수를 사용하기 전에 반드시 선언해야 한다는 규칙을 무시하므로 코드의 구조를 엉성하게 만들수 있다. 따라서 함수 표현식 사용을 권장하고 있다.

 

함수 표현식 방식과 함수 호이스팅

// 함수 표현식과 함수 호이스팅
// 함수 표현식으로 정의한 함수 변수는 호이스팅을 일으키지 않는다.
console.log(add2(2,3));    // uncaught type error
let add2 = function(x,y){
    return x+y;
};
console.log(add2(3,4));     // 7

위와 같이 함수 표현식으로 함수 변수를 생성하면 함수 변수 이전에 호출하는 add2 함수는 호출되지 않는다.

 

함수 호이스팅 발생 원인

자바스크립트의 변수 생성(Instantiation)과 초기화(Initialization)의 작업이 분리되서 진행되기 때문이다.

 

References

인사이드 자바스크립트, 송형주 저