함수와 일급 객체

2022. 11. 6. 18:25js

18.1 일급 객체

다음과 같은 조건을 만족하는 객체를 일급 객체 라 한다.

1. 무명의 리터럴로 생성할 수 있다. 런타임 생성이 가능하다.

2. 변수나 자료구조에 저장 할 수 있다.

3. 함수의 매개변수로 전달 할 수 있다.

4. 함수의 반환값으로 사용 할 수 있다.

사실 js 의 경우 거의 모든 경우에서 함수의 매개변수로 전달 할 수 있다. 따라서

이를 가지고 판단하는것은 조금 이해가 어려울 수 있다.

허나 위오 같은 일급 객체의 가장 큰 장점은 함수의 매개변수로 전달 할 수있고

매개변수의 반환값으로 전달 받을 수 있다.

이를 통해 함수형 프로그래밍을 가능케 해주는 이야기 이다.

위에서 말했듯 js에서 모든 함수는 매개변수로 전달 할 수 있기 때문에 모든 함수는 객체가 될 수 있다는

이야기인듯 하다.

18.2 함수 객체의 프로퍼티

js 에서 함수는 객체이기 때문에 함수는 내부 프로퍼티들이 존재한다. 이때

console.dir() 와 같은 함수를 통해서 브라우저에서 내부 프로퍼티들을 확인 할 수 있다.

18.2.1 arguments 프로퍼티

함수 객체의 arguments 프로퍼티 값은 arguments 객체 이다. 이때 이 객체는 함수 호출시

전달된 인수를 가지고 있는 유사 배열이다. 이때 함수 내부에서 지역변수로 사용 가능하다.

이때 js의 경우 매개변수의 개수와 실제로 들어온 인수의 개수가 같은지를 확인 하는 기능이 없기 때문에

이부분을 스스로 처리하는 부분을 거쳐야한다.

function test(a, b) {
   console.log(arguments);
}
test(10);

Arguments내부에 전달된 값들과 타입 등에 관련된 정보가 저장된 리스트가
들어온다.

를 출력하게 된다. 이때
Uncaught TypeError: Cannot read properties of undefined (reading 'test')
이때 위에서 내부 값을 사용한다거나 했을때 TypeError 와 같이
에러가 발생하는 것을 알 수 있다.

Arguments [10 , callee : f, Symbol(Symbol.iterator) : f]
  0 : 10
  callee : f. test(a, b)
  length : 1
  Symbol : f values()

와 같은 결과가 리턴된다.
이때 Arguments.는 배열은 아니기 때문에 foreach 와 같은 배열에서 사용하는
배열용 프로퍼티를 사용할 수 없기 때문에 for 와 같은 방식으로 순회 하거나 해야한다.

function test(a, b) {
    arguments.forEach((item) => console.log(item));
}
test(10);
VM1439:2 Uncaught TypeError: arguments.forEach is not a function
    at test (<anonymous>:2:15)
    at <anonymous>:1:1
와 같은 결과값을 내는것을 확인 할 수 있다 그렇기 때문에 위를 배열로 사용하기 위해서 
Array.prototype.slice.call(arguments)

와 같은 방식을 이용해서 배열로 사용하는 방식을 이용해야 한다.

18.2.2 caller 프로퍼티

어디서 이 함수가 호출되었는지를 확인 할 수 있는 프로퍼티로
this 를 자주 사용하는 class를 이용하는 코드를 작성할때 이 코드가 어디서 동작이 발생했는지를
확인 하기 위해서 사용 할 수 있다. 허나
위와 같은 caller 프로퍼티의 경우 표준 프로퍼티가 아님으로 크게 중점을 둘 필요가 없다고 함.

18.2.3 length 프로퍼티

선언한 매개변수의 개수를 확인 하는 녀석으로
선언한 매개변수의 개수와 arguments의 개수를 비교함으로 로직을 분기 할 수도 있을듯 하다 .

18.2.4 name 프로퍼티

es6 이전의 버전에 대해서는 볼 필요가 없다고 생각하기 때문에 글에서는 제거하고 es6이상의
버전에 대해서만 작성하도록 하겠다. 이때 익명함수 표현식으로 함수를 표현하였을때 이 함수의
이름을 선언된 변수의 이름으로 동작하여 어떨때 사용하는 함수였는지 확인이 조금더 편하게 할 수 있다.

18.2.5 proto 접근자 프로퍼티

모든 객체는 [[prototype]] 이라는 내부 슬롯을 가지고 상속을 구현하는 프로토 타입 객체를 가르킨다.
이때 프로토 타입 객체에 접근하기 위해서 사용하는 프로퍼티로
간접적으로는 접근가능하나 직접적으로 접근이 불가능하고 간접적으로 접근할 때 proto 접근자
프로퍼티를 이용하게 된다.

const obj = {
    study : function() {
        console.log('js-study');
    }
}
undefined
obj.__proto__

{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
constructor: ƒ Object()hasOwnProperty: ƒ hasOwnProperty()isPrototypeOf: ƒ isPrototypeOf()propertyIsEnumerable:
ƒ propertyIsEnumerable()toLocaleString: ƒ toLocaleString()toString: ƒ toString()valueOf: ƒ
valueOf()__defineGetter__: ƒ __defineGetter__()__defineSetter__: ƒ __defineSetter__()__lookupGetter__: 
ƒ __lookupGetter__()__lookupSetter__: ƒ __lookupSetter__()__proto__: (...)get __proto__:
ƒ __proto__()set __proto__: ƒ __proto__()

의 결과를 확인 할 수 있다.

18.2.6 prototype 프로퍼티

prototype 프로퍼티는 생성자 함수로 호출 할 수 있는 객체로 constructor 고유의 프로퍼티라고 할 수 있다.
이말은 생성자 함수에만 prototype 프로퍼티가 있다는 것을 의미한다.

'js' 카테고리의 다른 글

프로토타입 part2  (0) 2022.11.09
19 장 프로토타입 / part1  (0) 2022.11.08
생성자 함수에 의한 객체 생성  (0) 2022.11.05
js deep dive [프로퍼티 어트리뷰트]  (0) 2022.11.01
js deep dive [ 15 ]  (0) 2022.10.31