Skip to main content

함수

시작하기에 앞서

주의

해당 블로그의 모든 문서는 학습한 내용을 제 방식으로 정리하여 작성하고 있습니다.
순수 창작물도 아니고, 틀린 내용이 있을 수 있으므로 참고하고 읽어주시면 감사하겠습니다.

함수 정의

함수 선언문

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

const result = add(10, 20);
console.log(result); // 30

함수 선언문으로 함수의 정의입니다.

function키워드로 시작하고 add는 함수의 이름이 됩니다. 함수 선언문으로 함수를 정의할 때는 함수명이 필수입니다. 중괄호{ ... }안에서 함수의 기능에 해당하는 코드를 작성할 수 있고, return키워드를 사용해서 호출한 곳에 값을 반환할 수 있고, 반환하지 않을 수도 있습니다.

그리고 괄호()안의 xy는 매개변수로 함수를 호출할 때 값을 넘겨줄 수 있습니다. 5번 라인을 보면 함수명()형태로 함수를 호출하는 것을 볼 수 있는데, 10이 매개변수 x에 복사되고 20이 매개변수 y에 복사되며 x + y의 결과를 반환하므로 result 변수엔 30이 저장됩니다.

함수 호이스팅

자바스크립트에서 함수 선언문 방식은 유의할 점이 하나 있습니다.

바로 함수 호이스팅입니다.

함수 호이스팅
add(10, 20); // 30

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

1번 라인을 보면 add()함수를 호출하고 있습니다. 근데 뭔가 이상합니다. 함수를 호출하기 전에는 함수가 먼저 선언되어 있어야 할 것 같은데 자바스크립트에서는 정상적으로 동작합니다.

이게 왜 가능하냐면 자바스크립트에서는 함수 선언문 형태로 정의한 함수는 코드의 맨 위에 있는 것처럼 동작하기 때문입니다. 이를 함수 호이스팅이라고 합니다.

함수 호이스팅 발생X
add(10, 20); // uncaught type error

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

add(10, 20); // 30

함수 표현식 형태로 정의한 함수는 함수 호이스팅이 일어나지 않기 때문에 1번 라인에서는 에러가 발생합니다. 하지만, 정의하고 난 이후에 호출한 7번 라인에서는 정상적으로 호출됩니다.

함수 표현식

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

const result = add(10, 20);
console.log(result); // 30

자바스크립트에서는 함수도 하나의 값처럼 취급됩니다. 따라서 함수도 숫자나 문자열처럼 변수에 할당하는 것이 가능합니다. 생성된 함수를 변수에 할당하여 생성하는 방식을 함수 표현식이라고 합니다.

여기서 add변수는 함수 이름이 아니라, 생성한 함수를 참조하는 변수임을 유의해야 합니다. 함수 표현식으로 생성한 함수는 함수의 이름이 필수가 아니고, 위 예제에서도 함수의 이름이 없습니다. 이렇게 이름이 없는 함수를 익명 함수라고 합니다.

함수 객체

함수 객체
const add = function (x, y) {
return x + y;
};

add.result = add(10, 20);
console.log(add.result); // 30

자바스크립트에서는 함수도 객체입니다. 즉, 함수도 일반 객체처럼 프로퍼티들을 가질 수 있습니다.

그리고 5번 라인처럼 함수도 일반 객체처럼 프로퍼티를 동적으로 추가할 수 있고, 프로퍼티에 접근할 수 있다는 점도 확인할 수 있습니다.

변수나 프로퍼티에 함수 할당

// 변수에 함수 할당
const olaf = function (x, y) {
return x + y;
};

olaf(10, 20); // 30

const elsa = {};
// 객체의 프로퍼티에 함수 할당
elsa.add = function (x, y) {
return x + y
};

elsa.add(10, 20); // 30

자바스크립트에서는 함수도 하나의 값처럼 취급된다고 했습니다. 그렇다는 말은 2번 라인처럼 일반 변수에 함수를 할당할 수 있고, 10번 라인처럼 객체의 프로퍼티에도 함수를 할당할 수 있다는 말이 됩니다. 물론 배열의 원소에도 함수를 할당할 수 있습니다.

함수를 다른 함수의 인자로 넘기기

const olaf = function(add) {
// 인자로 넘겨받은 add 함수 호출
add(10, 20); // 30
};

olaf(function(x, y) {
return x + y;
});

함수도 하나의 값으로 취급되기 때문에 함수를 다른 함수의 인자로도 넘길 수 있습니다. 값으로 취급되기 때문에 함수의 return 값으로 함수를 사용하는 것도 가능합니다.

그냥 함수도 값으로 취급된다고 생각하고 있으면, 일반적으로 가능하지 않을까? 생각하고 있던 방법들은 거의 된다고 생각해도 무방할 듯합니다.

함수 객체의 프로토타입

function add() {
return x + y;
};

console.dir(add);

자바스크립트의 모든 객체는 프로토타입을 가지고 있습니다. 자바스크립트에서는 함수도 객체로 취급되므로 프로토타입을 가지고 있고, 함수의 프로토타입은 Function.prototype 객체입니다.

여기서 말하는 프로토타입이란, 모든 객체의 부모를 나타내는 [[Prototype]]을 의미합니다. 함수 객체가 가지는 prototype 프로퍼티와는 약간 다르므로 혼동하면 안 됩니다.

함수 객체의 length 프로퍼티

function f0() { 

}
function f1(x) {

}

console.log(f0.length); // 0
console.log(f1.length); // 1

모든 함수는 length 프로퍼티를 가집니다.

함수의 length 프로퍼티가 갖는 의미는 함수의 인자의 개수를 의미합니다.

참고 문서