Web/모던 자바스크립트 Deep Dive

[모던 자바스크립트 Deep Dive] 18. 함수와 일급 객체

동띵 2023. 9. 5. 11:55

일급 객체


  • 일급 객체 특징
    • 무명의 리터럴로 생성 가능 (즉, 런타임에 생성 가능)
    • 변수나 자료구조 (객체, 배열 등)에 저장 가능
    • 함수의 매개변수에 전달 가능
    • 함수의 반환값으로 사용 가능
  • 함수가 일급 객체라는 것은 함수를 객체와 동일하게 사용할 수 있다는 의미 ⇒ 함수는 값을 사용할 수 있는 곳이라면 어디서든지 리터럴로 정의 가능하며 런타임에 함수 객체로 평가
  • 함수와 일반 객체의 다른 점 : 함수는 호출 가능하지만 일반 객체는 호출 X, 함수는 일반 객체에 없는 함수 고유의 프로퍼티 소유

함수 객체의 프로퍼티


  • console.dir 메서드 사용하면 함수 객체의 내부 확인 가능
function square(number) {
	return number * number;
}
console.dir(square);
  • Object.getOwnPropertyDescription 메서드 사용하면 함수의 모든 프로퍼티의 프로퍼티 어트리뷰트 확인 가능
function square(number) {
	return number * number;
}

console.log(Object.getOwnPropertyDescription(square));
{
	length: ~~
	name: ~~
	arguments: ~~
	caller: ~~
	prototype: ~~
}

→ length, name, arguments, caller, prototype 프로퍼티는 모두 함수 객체의 데이터 프로퍼티 (일반 객체에 없는 함수 고유의 프로퍼티)

arguments 프로퍼티

  • arguments 객체
    • 함수 호출 시 전달된 인수들의 정보를 담고있는 순회 가능유사 배열 객체
      • 유사 배열 객체 : length 프로퍼티를 가진 채로 for 문으로 순회 가능한 객체 (배열 메서드 사용 불가)
        • 유사 배열 객체에 배열 메서드를 사용하기 위해서는 Function.prototype.call, Function.prototype.apply/call/bind 메서드를 사용하거나 인자에 spread 연산자를 사용 (ES6 Rest 파라미터)
    • 함수 내부에서 지역 변수처럼 사용되어 외부에서 참조 X
    • 매개변수와 인수의 개수가 일치하는지 확인 X
    • arguments 객체의 callee 프로퍼티 : 함수 자기 자신을 가리킴
    • arguments 객체의 length 프로퍼티 : 인수의 개수를 가리킴
  • 함수 호출 시 인자 개수 확인하고, 이에 따라 함수의 동작을 달리 정의할 필요가 있을 때 유용하게 사용
function sum() {
	let res = 0;
	
	for (let i = 0; i < arguments.length; i++) {
		res += arguments[i];
	}
	
	return res;
}

conosole.log(sum()); // 0
conosole.log(sum(1, 2)); // 3
conosole.log(sum(1, 2, 3)); // 6

// 배열 메서드 사용하고 싶은 경우
function sum() {
	// arguments 객체를 배열로 변환
	const array = Array.prototype.slice.all(arguments);
	return array.reduce(function(pre, cur) {
		return pre+cur;
	}, 0);
}

function sum(...args) { // ES6 Rest 파라미터 사용
	return args.reduce((pre, cur) => pre+cur, 0);
}

caller 프로퍼티

  • ESMAScript 사양에 포함되지 않은 비표준 프로퍼티
  • 자기 자신을 호출한 함수 가리킴

length 프로퍼티

  • 함수 정의할 때 선언한 매개변수 개수를 가리킴
  • arguments 객체의 length 프로퍼티는 인자의 개수를, 함수 객체의 length 프로퍼티는 매개변수의 개수를 가리킴

name 프로퍼티

  • 함수 이름을 나타냄
  • ES6 이전까지는 비표준이었다가 ES6에서 정식 표준 됨
  • 익명 함수 표현식의 경우 ES5에서 name 프로퍼티는 빈 문자열을 값으로 가졌지만, ES6의 경우 함수 객체를 가리키는 식별자를 값으로 가짐
// 기명 함수 표현식
var namedFunc = function foo() {};
console.log(namedFunc.name) // foo

// 익명 함수 표현식
var anonymousFunc = function() {};
console.log(anonymousFunc.name) // ES5에서는 빈문자열을, ES6에서는 anonymousFunc

// 함수 선언문
function bar() {}
console.log(bar.name) // bar

__proto__ 접근자 프로퍼티

  • [[Prototype]] 내부 슬롯이 가리키는 프로포타입 객체에 접근하기 위해 사용하는 접근자 프로퍼티

prototype 프로퍼티

  • 생성자 함수로 호출할 수 있는 함수 객체, 즉 constructor만이 소유하는 프로퍼티
  • 일반 객체와 생성자 함수로 호출할 수 없는 non-constructor에는 prototype 프로퍼티 X
  • 생성자 함수가 생성할 인스턴스의 프로포타입 객체를 가리킴