일급객체
- 무명의 리터럴로 생성가능 → 런타임에 생성 가능
- 변수나 자료구조에 저장할 수 있음
- 함수의 매개변수에 전달할 수 있음
- 함수의 반환값으로 사용 가능함
함수와 객체를 동일하게 사용할 수 있음
즉, 함수는 값을 사용하는 곳에는 어디든 리터럴로 정의할 수 있고, 이를 런타임에 함수객체로 평가하게 됨
가장 큰 특징
- 매개변수에 전달할 수 있음
- 함수의 반환값으로 사용가능
함수 객체의 프로퍼티
Object.getOwnPropertyDescriptors(f);
{length: {…}, name: {…}, arguments: {…}, caller: {…}, prototype: {…}}
arguments: {value: null, writable: false, enumerable: false, configurable: false}
caller: {value: null, writable: false, enumerable: false, configurable: false}
length: {value: 0, writable: false, enumerable: false, configurable: true}
name: {value: 'f', writable: false, enumerable: false, configurable: true}
prototype: {value: {…}, writable: true, enumerable: false, configurable: false}
[[Prototype]]: Object
arguments, caller, length, name, prototype프로퍼티는 모두 함수 객체의 데이터 프로퍼티임
arguments 프로퍼티
함수 호출시 전달된 인수의 정보를 담고 있는 순회 가능한 유사 배열 객체임
함수 내부에서 지역변수처럼 사용됨
함수 내부에서 arguments를 통해 사용가능함
함수의 인수는 undefined로 초기화 되어 이후 들어오는 값을 받으므로, 인수가 적은 경우에는 undefined가 남게되고, 많은 경우에는 무시되나 arguments객체에 저장된다.
const f=function(){
console.log(arguments);
};
f(1,2,3,4,5);
Arguments(5) [1, 2, 3, 4, 5, callee: ƒ, Symbol(Symbol.iterator): ƒ]
0: 1
1: 2
2: 3
3: 4
4: 5
callee: ƒ ()
length: 5
Symbol(Symbol.iterator): ƒ values()
[[Prototype]]: Object
프로퍼티 키는 인수의 순서를, calle프로퍼티는 arguments 객체를생성한 함수, 즉 자기 자신을 가리키고, length는 인수의 길이를 말한다.
Symbol.iterator
해당 프로퍼티는 arguments 객체를 순회 가능한 자료구조인 이터러블로 만들기 위한 프로퍼티이다.
Symbol.iterator키를 통해 해당 프로퍼티에 접근할 수 있다.
next를 통해 다음 arguments에 접근 가능하다.
function multiply(x, y) {
const iterator = arguments[Symbol.iterator]();
console.log(iterator.next()); //{ value: 1, done: false }
console.log(iterator.next()); //{ value: 2, done: false }
console.log(iterator.next()); //{ value: undefined, done: true }
}
multiply(1, 2);
arguments를 통해 가변 인자 함수를 구현할 수 있다.
function sum(){
let res=0;
for (let x=0; x<arguments.length; x++){
res+=arguments[x];
}
return res;
}
sum(1,2,3) //6
유사배열객체
유사배열객체는 배열이 아니므로 배열 메서드를 사용하는 경우 에러가 발생한다.
따라서 이렇게 사용한다.
function sum(){
const array=Array.prototype.slice.call(arguments);
return array.reduce(function(pre, cur){
return pre+cur;
},0);
}
Rest 파라미터
ES6에서는 이런 번거로움을 줄이기 위해Rest 파라미터를 도입했다.
function sum(...args){
return args.reduce((pre,cur)=>pre+cur,0);
}
caller 프로퍼티
비표준 프로퍼티이다. 알 필요 없다.
자신을 호출한 함수를 가리킨다.
length 프로퍼티
함수를 정의할 때 선언한 매개변수의 개수를 가리킨다.
function x(x, y, z) {}
console.log(x.length); //3
arguments의 length와는 다른 프로퍼티이다.
arguments의 length는 인자의 개수를, length 프로퍼티는 매개변수의 개수를 가리킨다.
name프로퍼티
함수이름을 나타냄
ES6에서 표준이 되어서 ES5에서는 다르게 작동함
function foo() {}
const bar = function () {};
const test = function nottest() {};
console.log(foo.name); //foo
console.log(bar.name); //bar, ES5에서는 ""
console.log(test.name); //nottest
__proto __ 접근자 프로퍼티
모든 객체는 [[Prototype]]이라는 내부 슬롯을 갖는다. proto프로퍼티는 이 내부 슬롯이 가리키는 프로토타입 객체에 접근하기 위해 사용하는 접근자 프로퍼티이다.
const obj = { a: '1' };
console.log(obj.__proto__ === Object.prototype);
hasOwnProperty
해당 객체 고유의 프로퍼티 키인 경우만 true를 반환함
console.log(obj.hasOwnProperty('a')); //true
console.log(obj.hasOwnProperty('__proto__')); //false