본문 바로가기
JavaScript/Deep Dive

18 함수와 일급 객체

by lacuca9 2024. 9. 26.

일급 객체 조건

  • 런타임에 생성이 가능
  • 변수나 자료구조(객체, 배열)에 저장할 수 있다
  • 함수의 매개변수에 전달할 수 있다
  • 함수의 반한값으로 사용할 수 있다

함수가 일급 객체라는 것은 함수를 객체와 동일하게 사용할 수 있다는 의미.

함수는 값을 사용할 수 있는 곳(변수 할당문, 객체의 프로퍼티 값, 배열의 요소, 함수 호출의 인수, 함수 반환문)

이라면 어디서든지 리터럴로 정의할 수 있으며 런타에 함수 객체로 평가됨.

// 1. 함수는 무명의 리터럴로 생성할 수 있다.
// 2. 함수는 변수에 저장할 수 있다.
// 런타임(할당 단계)에 함수 리터럴이 평가되어 함수 객체가 생성되고 변수에 할당된다.
const increase = function (num) {
  return ++num;
};
const decrease = function (num) {
  return --num;
};

// 2. 함수는 객체에 저장할 수 있다.
const auxs = { increase, decrease };

// 3. 함수의 매개변수에게 전달할 수 있다.
// 4. 함수의 반환값으로 사용할 수 있다.
function makeCounter(aux) {
  let num = 0;
  return function () {
    num = aux(num);
    return num;
  };
}

// 3. 함수는 매개변수에게 함수를 전달할 수 있다.
const increaser = makeCounter(auxs.increase);
console.log(increaser()); // 1
console.log(increaser()); // 2

// 3. 함수는 매개변수에게 함수를 전달할 수 있다.
const decreaser = makeCounter(auxs.decrease);
console.log(decreaser()); // -1
console.log(decreaser()); // -2

 

arguments 프로퍼티

arguments 객체는 함수 호출 시 전달된 인수(argument)들의 정보를 담고 있는 순회 가능한 유사 배열 객체이며,

함수 내부에서 지역 변수처럼 사용된다. 즉 함수 외부에서는 참조할 수 없다.

 

arguments객체는 매개변수 개수를 확정할 수 없는 가변 인자 함수를 구현할 때 유용하다.

function sum() {
  let res = 0;
  // arguments 객체는 length 프로퍼티가 있는 유사 배열 객체이므로 for 문으로 순회할 수 있다.
  for (let i = 0; i < arguments.length; i++) {
    res += arguments[i];
  }
  return res;
}
console.log(sum());        // 0
console.log(sum(1, 2));    // 3
console.log(sum(1, 2, 3)); // 6

 

arguments 객체는 유사 배열 객체(array-like object)

유사 배열 객체란? length 프로퍼티를 가진 객체로 for문으로 순회할 수 있는 객체

특징 유사 배열 객체 배열
생성 방식 객체 리터러르 특정 내장 객체(e.g. NodeList, arguments) 배열 리터럴( [ ] ), Array 생성자
메서드 지원 배열 메서드 사용 불가 배열 메서드 사용 가능 ( push, map, filter 등 )
length 속성 있음 있음
프로토타입 일반 객체 프로토타입 Array.prototype
변환 방법 Array.from() 또는 slice()를 사용해 배열로 변환 가능 -

 

ES6에선 Rest 파라미터를 도입함.

// ES6 Rest parameter
function sum(...args) {
  return args.reduce((pre, cur) => pre + cur, 0);
}

console.log(sum(1, 2));          // 3
console.log(sum(1, 2, 3, 4, 5)); // 15

 

arguments 객체의 length 프로퍼티는 인자(argument)의 개수를 가리키고,

함수 객체의 length 프로퍼티는 매개변수(parameter)의 개수를 가리킨다.

function foo() {}
console.log(foo.length); // 0

function bar(x) {
  return x;
}
console.log(bar.length); // 1

function baz(x, y) {
  return x * y;
}
console.log(baz.length); // 2

 

name 프로퍼티는 함수 이름을 나타낸다.

 

__proto__ 접근자 프로퍼티

[[Prototype]] 내부 슬롯이 가리키는 프로토타입 객체에 간접적으로 접근하기 위해 사용하는 접근자 프로퍼티다.

const obj = { a: 1 };
// 객체 리터럴 방식으로 생성한 객체의 프로토타입 객체는 Object.prototype이다.
console.log(obj.__proto__ === Object.prototype); // true

// 객체 리터럴 방식으로 생성한 객체는 프로토타입 객체인 Object.prototype의 프로퍼티를 상속받는다.
// hasOwnProperty 메서드는 Object.prototype의 메서드다.
console.log(obj.hasOwnProperty('a'));         // true
console.log(obj.hasOwnProperty('__proto__')); // false

 

 

 

 

 

 

 

'JavaScript > Deep Dive' 카테고리의 다른 글

19 프로토타입 (2)  (0) 2024.09.28
19 프로토타입 (1)  (1) 2024.09.26
17 생성자 함수에 의한 객체 생성  (2) 2024.09.25
16 프로퍼티 어트리뷰트  (0) 2024.09.23
15 let, const 키워드와 블록 레벨 스코프  (0) 2024.09.23