함수와 일급 객체
Deep DIve 10장
18장 일급객체
18.1 일급객 체란?
다음과 같은 조건을 만족하는 객체를 일급 객체라 한다.
- 무명의 리터럴로 생성할 수 있다. 즉, 런타임에 생성이 가능하다.
- 변수나 자료구조(객체, 배열 등)에 저장할 수 있다.
- 함수의 매개변수에 전달할 수 있다.
- 함수의 반환값으로 사용할 수 있다.
ex) 자바스크립트 함수
//1. 함수는 무명의 리터럴로 생성할 수 있다.
//2. 함수는 변수에 저장할 수 있다.
// 런타임(할당 단계)에 함수 리터럴이 평가되어 함수 객체가 생성되고 변수에 할당된다.
const increase = function (num) {
retrun ++num;
};
const decrease = function(num) {
return --num;
};
// 2. 함수는 객체에 저장할 수 있다.
const predicates = {increase, decrease} ;
// 3. 함수의 매개변수에 전달할 수 있다.
// 4. 함수의 반환값으로 사용할 수 있다.
function makeCounter(predicate){
let num = 0;
return function () {
num predicate(num);
return num;
};
}
//3. 함수는 매개변수에게 함수를 전달할 수 있다.
const increaser = makeCounter(predicates.increase);
console.log(increaser()); //1
console.log(increaser()); //2
//3. 함수는 매개변수에게 함수를 전달할 수 있다.
const decreaser = makeCounter(predicates.decrease);
console.log(decreaser()); //-1
console.log(decreaser()); //-2
함수가 일급 객체라는 것은 함수를 객체와 동일하게 쓸 수 있다는 의미다. 객체는 값이므로 함수는 값과 동일하게 취급할 수 있다. 따라서 함수는 값을 사용할 수 있는 곳(변수 할당문, 객체의 프로퍼티 값, 배열의 요소, 함수 호출의 인수, 함수 반환문) 이라면 어디서든지 리터럴로 정의할 수 있으며 런타임에 함수 객체로 평가된다.
일급 객체로서 함수가 가지는 가장 큰 특징은 일반 객체와 같이 함수의 매개변수에 전달할 수 있으며, 함수의 반환값으로 사용할 수도 있다.
함수는 객체지만 일반 객체와의 차이가 있다. 일반 객체 호출 불가능. 함수 객체는 호출 가능. 그리고 함수 고유의 프로퍼티를 소유함.
18.2 함수 객체의 프로퍼티
함수는 객체이므로 프로퍼티를 가질수 있다. arguments, caller, length, name, prototype 프로퍼티는 모두 함수 객체의 데이터 프로퍼티다. 함수 객체 고유의 프로퍼티.
18.2.1 arguments 프로퍼티
arguments 프로퍼티 값은 arguments 객체다. 객체는 함수 호출 시 전달된 인수들의 정보를 담고있는 순회 가능한 유사 배열 객체며, 함수 내부에서 지역 변수처럼 사용된다. 함수외부에서는 참조할 수 없다.
function multiply(x, y) {
console.log(arguments);
return x * y ;
}
console.log(multiply());
console.log(multiply(1));
console.log(multiply(1, 2));
자바스크립트는 함수를 호출할 때 전달하는 인수의 개수를 확인하지 않아서 함수가 호출되면인수 개수에 따라 함수 동작을 달리 정의할 필요가 있는데, 이 때 유용하게 사용되는 것이 arguments 객체임. 매개변수를 확정할 수 없는 가변 인자 함수를 구현할 때 유용
18.2.2 caller 프로퍼티
함수 자신을 호출한 함수를 가리킨다. 표준화 예정없는 프로퍼티라 참고로만 알아두자.
18.2.3 length 프로퍼티
함수를 정의할때 선언한 매개변수의 개수를 가리킨다.
18.2.4 name 프로퍼티
함수 이름을 나타낸다.
18.2.5 proto 접근자 프로퍼티
객체에 접근하기 위해 사용하는 접근자 프로퍼티다. 내부 슬롯에는 직접 접근할 수 없어 proto 접근자 프로퍼티를 통해 프로토 타입 객체에 접근할 수 있다.
const obj = { a:1 }'
//객체 리터럴 방식으로 생성한 객체의 프로토타입 객체는 Object.prototype이다.
console.log(obj.__proto__ === Object.prototype); // true
// 객체 리터럴 방식으로 생성한 객체는 프로토타입 객체인 Object.prototpye의 프로퍼티를 상속받는다.
// hashOwnProperty 메서드는 Object.prototype의 메서드다.
console.log(obj.hashOwnProperty('a'); // true
console.log(obj.hashOwnProperty('__prototype__'); // false
hashOwnProperty 메서드는 이름에서 알수 있듯이 인수로 전달받은 프로퍼티 키가 객체 고유의 프로퍼티 키인 경우에만 true를 반환하고 상속받은 프로퍼티 키인 경우 false를 반환한다.)
18.2.6 _prototype 프로퍼티
생성자 함수로 호출할 수 있는 객체, 즉 construtctor 만이 소유하는 프로퍼디. 일반 객체와 생성자 함수로 호출할 수 없는 non-constructor에는 프로토 타입 프로퍼티가 없다.