4.2 함수 객체 : 함수도 객체다
자바스크립트에서는 함수도 객체다
함수도 객체다 : 함수의 기본 기능인 코드 실행뿐만 아니라, 함수 자체가 일반 객체처럼 프로퍼티들을 가질 수 있다.
예제 4-8 add() 함수도 객체처럼 프로퍼티를 가질 수 있다.
// 함수 선언 방식으로 add()함수 정의
function add(x, y) {
return x+y;
}
// add() 함수 객체에 result, status프로퍼티 추가
add.result = add(3, 2);
add.status = 'OK';
console.log(add.result); // (출력값) 5
console.log(add.status); // (출력값) 'OK'
함수 선언문 방식으로 add()
함수를 생성한 후, add()
함수가 일반 객체처럼 result
와 status
프로퍼티를 추가하는 게 가능
add()
함수를 생성할 때 함수 코드는 함수 객체의[[Code]]
내부 프로퍼티에 자동으로 저장됨.
자바스크립트에서 함수는 값으로 취급된다.
자바스크립트에서 함수는 객체다 : 함수도 일반 객체처럼 취급될 수 있다.
때문에 자바스크립트 함수는 다음과 같은 동작이 가능
- 리터럴에 의해 생성
- 변수나 배열의 요소, 객체의 프로퍼티 등에 할당 가능
- 함수의 인자로 전달 가능
- 함수의 리턴값으로 리턴 가능
- 동적으로 프로퍼티를 생성 및 할당 가능
자바스크림트에서는 함수를 일급(First Class) 객체라고 부름.
컴퓨터 프로그래밍 언어 분야에서 앞에서 나열한 기능이 모두 가능한 객체를 일급 객체라고 부른다.
함수가 일급 객체 함수가 일반 객체처럼 값(Value)으로 취급된다.
함수를 변수나 객체, 배열 등에 값으로도 저장할 수 있으며, 다른 함수의 인자로 전달한다거나 함수의 리턴값으로도 사용 가능하다.
4.2.2.1 변수나 프로퍼티의 값으로 할당
예제 4-9 변수나 프로퍼티에 함수값을 할당하는 코드
// 변수에 함수 할당
var foo = 100;
var bar = function () {return 100; };
console.log(bar()); // (출력값) 100
// 프로퍼티에 함수 할당
var obj = {};
obj.baz = function () {return 200; };
console.log(obj.baz()); // (출력값) 200
- 함수는 객체의 프로퍼티나 배열의 원소 등에도 할당이 가능하다.
4.2.2.2 함수 인자로 전달
예제 4-10 함수를 다른 함수의 인자로 넘긴 코드
// 함수 표현식으로 foo() 함수 생성
var foo = function(func) {
func(); // 인자로 받은 func() 함수 호출
};
// foo() 함수 실행
foo(function() {
console.log('Function can be user as the argument');
});
foo()
함수를 호출할 때, 함수 리터럴 방식으로 생성한 익명 함수를func
인자로 넘김.
4.2.2.3 리턴값으로 활용
예제 4-11 함수를 다른 함수의 리턴값으로 활용한 코드
// 함수를 리턴하는 foo() 함수 정의
var foo = function() {
return function() {
console.log('this function is the return value.')
};
};
var bar = foo();
bar();
foo()
함수가 호출되면 리턴값으로 전달되는 함수가bar
변수에 저장된다.()
함수 호출 연산자를 이용해bar()
로 리턴된 함수를 실행
4.2.3 함수 객체의 기본 프로퍼티
자바스크립트에서는 함수 역시 객체다 : 함수 역시 일반적인 객체의 기능에 추가로 호출됐을 때 정의된 코드를 실행하는 기능을 가지고 있다. + 일반 객체와는 다르게 추가로 함수 객체만의 표준 프로퍼티가 정의되어 있다.
예제 4-12 add() 함수 객체 프로퍼티를 출력하는 코드
function add(x, y) {
return x + y;
}
console.dir(add);
add()
함수는 arguments
, caller
, length
등과 같은 다양한 프로퍼티가 기본적으로 생성되어 있음.
ECMA5 스크립트 명세서에는 모든 함수가 length
와 prototype
프로퍼티를 가져야 한다고 기술.
name
, caller
, argument
, __proto__
프로퍼티들은 ECMA 표준이 아니다.
name
: 함수의 이름. 익명 함수라면 빈 문자열caller
: 자신을 호출한 함수. 호출하지 않으면null
arguments
: 함수를 호출할 때 전달된 인자값. 현재는add()
함수가 호출된 상태가 아니므로null
arguments 객체
arguments
프로퍼티와 같은 이름으로 ECMA 표준에서는 arguments
객체를 정의. arguments
객체는 함수를 호출할 때 호출된 함수의 내부로 인자값과 함께 전달되며, arguments
프로퍼티와 유사하게 함수를 호출할 때 전달 인자값의 정보 제공. (4.4.1에서 더 자세히 알아봄)
__proto__
:add()
함수 역시 자바스크립트 객체이므로[[Prototype]]
프로퍼티인__proto__
프로퍼티를 가짐.add()
와 같은 함수 객체의 부모 역할을 하는 프로토타입 객체Function.prototype
객체, 이 역시 함수 객체 실제로 크롬 브라우저에서Function Prototype
객체를Empty()
(f()
) 함수라고 명명. 이 역시 함수 객체이므로name
,caller
,arguments
등과 같은 함수 객체의 프로퍼티를 가짐.
Function.prototype 객체의 프로토타입 객체
모든 함수들의 부모 객체는 Function Prototype
객체.
Function Prototype
도 함수.
예외적으로 Function Prototype
함수 객체의 부모는 Object.prototype
객체
Function.prototype
객체가 가져야 하는 프로퍼티들
constructor
프로퍼티toString()
메서드apply (thisArg, argArray)
메서드call (thisArg, [, arg1 [, arg2, ]])
메서드bind (thisArg, [, arg1 [, arg2]])
메서드
이 가운데 특히 apply()
, call()
는 실제로 자주 사용되는 중요한 메서드 (4.4.2.4에서 더 자세히 살펴봄)
4.2.3.1 length 프로퍼티
예제 4-13 함수 객체의 length 프로퍼티
function func0() {
}
function func1(x) {
return x;
}
function func2(x, y) {
return x + y;
}
function func3(x, y, z) {
return x + y + z;
}
console.log('func0.length - ' + func0.length); // (출력값) func0.length - 0
console.log('func1.length - ' + func1.length); // (출력값) func1.length - 1
console.log('func2.length - ' + func2.length); // (출력값) func2.length - 2
console.log('func3.length - ' + func3.length); // (출력값) func3.length - 3
인자 개수가 서로 다른 함수들 함수 객체의 length
프로퍼티는 함수를 작성할 때 정의한 인자 개수
4.2.3.2 prototype 프로퍼티
모든 함수는 객체로서 prototype 프로퍼티를 가짐.
함수 객체의 prototype 프로퍼티는 모든 객체의 부모를 나타내는 내부 프로퍼티인 [Prototype]과 혼동하지 말아야 한다.prototype 프로퍼티와 [Prototype] 프로퍼티
공통점 : 두 프로퍼티 모두 프로토타입 객체를 가리킨다.
but 관점에 차이.
[[Prototype]]
: 모든 객체가 가짐. 객체 입장에서 자신의 부모 역할을 하는 프로토타입 객체
prototype
: 함수 객체만 가짐. 이 함수가 생성자로 사용될 때 이 함수를 통해 생성된 객체의 부모 역할을 하는 프로토타입 객체 (4.5.1 프로토타입의 두 가지 의미에서 자세히 살펴봄)
prototype 프로퍼티는 함수가 생성될 때 만들어지며, constructor
프로퍼티 하나만 가진다. 이 constructor
프로퍼티는 자신과 연결된 함수를 가리킨다.
즉, 자바스크립트에서는 함수를 생성할 때, 함수 자신과 연결된 프로토타입 객체를 동시에 생성하며, 이 둘은 각각 prototype
과 constructor
라는 프로퍼티로 서로를 참조한다.
프로토타입 객체 네이밍
함수의 prototype
프로퍼티가 가리키는 프로토타입 객체는 일반적으로 따로 네이밍하지 않고, 자신과 연결된 함수의 prototype
프로퍼티값을 그대로 이용.
예) add()
함수의 프로토타입 객체는 add.prototype
예제 4-14 함수 객체와 프로토타입 객체와의 관계를 보여주는 코드
// MyFunction() 함수 정의
function myFunction() {
return true;
}
console.dir(myFunction.prototype);
console.dir(myFunction.prototype.constructor);
함수 객체와 프로토타입 객체는 서로 밀접하게 연결되어 있음.
#책/인사이드자바스크립트
'language > JavaScript' 카테고리의 다른 글
4. 함수와 프로토타입 체이닝 (4) (0) | 2019.11.22 |
---|---|
4. 함수와 프로토타입 체이닝 (3) (0) | 2019.11.21 |
4. 함수와 프로토타입 체이닝 (1) (0) | 2019.11.21 |
3. 자바스크립트 데이터 타입과 연산자 (3) (0) | 2019.11.19 |
3. 자바스크립트 데이터 타입과 연산자 (2) (0) | 2019.11.19 |