미누에요
[JavaScript] 함수는 왜 객체인가 ? 본문
JavaScript에서 함수는 객체이다.
그 이유는 함수가 객체와 비슷하게 저장되고 사용가능하기 때문이라고 익히 들었을 것이다.
이에 대해서 더 자세히 들여다보자.
우선 함수는, JavaScript가 말하는 일급 객체의 성질을 모두 만족한다.
그렇기 때문에 함수는 객체이다 라는 말이 성립하는 것이다.
일급 객체는 아래의 조건을 가진다.
- 무명의 리터럴로 생성할 수 있다. (런타임에 의해 생성이 가능하다)
- 변수나 자료구조(객체, 배열 등)에 저장할 수 있다.
- 함수의 매개변수에 전달할 수 있다.
- 함수의 반환값으로 사용할 수 있다.
하나씩 차근차근 살펴보자.
우선, 함수는 무명의 리터럴로 생성이 가능하다. 우리는 익명 함수를 통해 변수에 할당하는 경험을 해보았다.
const add = function (a,b){
return a+b;
}
그리고 이 함수를 객체에 저장할 수 있다.
const obj = { add };
또한 이 함수를 함수의 매개변수로 사용할 수 있다.
function callbackOne(a,b,callback){
return callback(a,b);
}
반환값 역시 사용이 가능하다.
function callbackOne(a,b,callback){
return function(){
return callback(a,b);
}
}
위 조건을 모두 만족하므로 함수는 일급 객체이다. 즉, 함수는 객체와 동일하게 사용할 수 있다.
함수가 객체라면, 함수도 객체처럼 프로퍼티를 가지고 있을 것이다.
함수는 위 사진에서 보이는 것과 같이 arguments, caller, length, name, 그리고 prototype 프로퍼티를 가진다.
각 프로퍼티에 대해서 알아보자.
arguments
arguments는 함수 호출 시 전달된 인자들을 객체 형식으로 담고 있다. 함수 내에서 접근가능한 지역 변수이다.
Function.arguments로 접근할 수 있지만, 이제는 권장하지 않는 방법이라고 한다.
따라서 우리는 그냥 arguments로 접근할 수 있다.
- arguments에 인자가 전달되고, 매개변수에 맞게 매칭되는 시스템
- JavaScript에서는 함수 arguments의 개수를 확인하지 않기 때문에 매개변수의 개수만큼 인자를 전달하지 않아도 에러가 발생하지 않는다. (NaN 만 발생)
- 매개변수보다 많은 인자를 전달하면 앞에서부터 필요한 만큼만 사용하고, 나머지는 arguments에 저장되어 있다.
따라서 매개변수를 a, b 와 같이 설정하지 않고 arguments 하나로 설정하여 가변 인자 함수를 구현할 수 있게 되는것이다.
caller
누가 호출했는지에 대한 정보를 가지고 있다.
첫번째 console.log에는 a가 b를 호출했으므로 a가 나오고, 두번째 console.log에서는 b()를 호출한 함수는 없으므로 null이 나오게 된다.
length
함수를 정의할 때 선언한 매개변수의 길이에 대한 정보를 가지고 있다.
name
함수 이름을 나타내는 프로퍼티로, ES6부터 정식 표준이 되었다.
- 익명 함수 표현식의 경우 ES5에서는 빈 문자열을 가지므로 주의 (ES6에서는 식별자를 값으로 가짐)
prototype
prototype 프로퍼티는 생성자 함수로 사용할 수 있는 객체인 constructor가 소유하는 프로퍼티이다.
이처럼 JavaScript에서 함수는 일급 객체이고, 객체처럼 사용된다.
일급객체로써의 함수 사용이 JavaScript의 함수형 프로그래밍에 중요한 요점이니 함수가 왜 일급객체인지 잘 익혀두면 좋을 거 같다.