본문 바로가기

2주차

일급 객체와 JS 함수 뜯어보기

 

안녕하세요 웹 파트 YB 곽지욱입니다 😀 이번 공유 과제에서는 지난 세미나에서 언급된 일급 객체JS 함수에 대해서 알아보았습니다 😃

일급 객체

 

일급객체란 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 가리킨다.

 

일급객체란 구체적으로는 다음과 같은 조건을 만족하는 객체를 일급 객체라고 한다.

  1. 무명의 리터럴로 생성할 수 있다. 즉, 런타임에 생성이 가능하다.
  2. 변수나 자료구조(객체, 배열 등)에 저장할 수 있다.
  3. 함수의 매개변수에 전달할 수 있다.
  4. 함수의 반환 값으로 사용할 수 있다.

자바스크립트의 함수는 위의 조건을 모두 만족하는 일급 객체이다.

다른 건 다 직관적으로 이해할 수 있겠지만, 헷갈릴 수 있는 1번 조건에 대해 알아보자.

// 1. 무명의 리터럴로 생성 후 즉시 실행 (IIFE - 즉시 실행 함수 표현)
(function() {
  console.log('이 함수는 무명 리터럴로 런타임에 생성되고 바로 실행됩니다!');
})();
  • 위 코드는 함수를 function 키워드로 정의했지만 이름을 붙이지 않은 익명 함수이다.
  • 이 익명 함수는 정의와 동시에 즉시 실행(IIFE) 된다. 이런 방식은 함수를 특정 시점에 런타임에서 직접 생성하고 바로 사용하고자 할 때 많이 활용된다.
  • 여기서 런타임에 생성 가능하다는 의미가 무엇이냐?

런타임은 프로그램이 실행 중일 때를 의미한다. 즉, 런타임에 생성 가능하다는 것은 프로그램이 실행되는 도중에 필요한 시점에 함수를 새로 생성하고 사용할 수 있는 뜻을 말한다.

런타임 생성의 차이

function sayHello() {
  console.log("Hello!");
}
sayHello();  // "Hello!" 출력

 

이렇게 정적으로 함수를 선언한 경우, 프로그램이 시작되기 전에 미리 정의되는 것이다.

다시 말하면 이 함수는 코드가 실행되기 전에 메모리에 올라가 공간을 차지하는 것.

변수에 무명 함수 저장

const greet = function() {
  console.log("Hello, World!");
};
greet();  // "Hello, World!" 출력

 

이 경우 익명 함수를 프로그램이 실행되는 도중 즉, 런타임에 생성한다.

함수를 정의한 코드가 실행될 때 비로소 메모리에 함수가 생성되고, 변수 greet에 저장된다.

그래서 리터럴이란?

  • 리터럴이란 코드를 작성할 때 고정된 값 자체를 표현하는 방식을 말한다.
  • 프로그래밍 언어에서, 리터럴은 값을 직접 코드에 명시하는 것을 말한다.

즉, 함수 리터럴은 함수에 이름을 붙이지 않고, 곧 바로 코드에서 익명함수로 사용할 수 있는 것을 의미한다.

그래서 런타임 생성과 사용이 왜 유용한데?

  • 런타임에 함수를 생성한다는 것은 유연하게 함수 필요할 때 만들어 사용할 수 있다는 뜻을 말한다.
  • 이를 통해 코드가 동적으로 변경되는 상황에 대응할 수 있다. 예를 들어 클릭 이벤트가 발생할 때마다 새로운 함수를 만들고 호출할 수 있는 것.
document.getElementById('myButton').addEventListener('click', function() {
  console.log('버튼이 클릭되었습니다!');
});
  • 우리가 자주 보는 이 문법은 사실 버튼 클릭 시 익명 함수를 즉석에서(런타임에) 생성하고 실행하는 것이다.
  • 미리 정의된 함수 없이 이벤트가 발생할 때마다 필요한 함수를 동적으로 생성하기 때문에 메모리 관리의 효율성 또한 상승할 수 있는 것.

함수의 전달

일급 객체로서 함수가 가지는 가장 큰 특징은 함수의 매개변수에 전달할 수 있으며, 함수의 반환 값으로 사용할 수 있다는 것이다.

이는 함수형 프로그래밍을 가능케 하는 자바스크립트의 장점 중 하나다.

function repeatAction(n, action) {
  for (let i = 0; i < n; i++) {
    action();  // 전달된 함수 실행
  }
}

// 'Hello'를 3번 출력하는 익명 함수 전달
repeatAction(3, function() {
  console.log("Hello!");
});

이처럼 함수를 매개변수로 전달해 특정 로직을 유연하게 적용하는 것이 가능하다.

함수 객체의 프로퍼티

브라우저 콘솔에서 console.dir를 입력해서 함수 객체의 내부를 쉽게 들여다 볼 수 있다.

 

왜 함수 객체의 프로퍼티를 이해해야 할까?

 

1. 함수도 객체이기 때문

* 자바스크립트에서는 함수도 일급 객체로 취급 되기 때문이다. 이는 함수가 변수에 할당되거나, 다른 함수의 인자로 전달, 함수에서 반환될 수 있다는 의미이다.

* 함수를 객체처럼 다룰 수 있기 때문에 프로퍼티와 메서드를 추가하거나 내장된 프로퍼티에 접근하는 것 또한 가능하기 때문.

function exampleFunction(a, b) {
  return a + b;
}

// 브라우저 콘솔에서 함수 객체의 내부를 확인
console.dir(exampleFunction);
ƒ exampleFunction(a, b)
  arguments: null
  caller: null
  length: 2
  name: "exampleFunction"
  prototype: {constructor: ƒ}
  [[FunctionLocation]]: script.js:1
  [[Scopes]]: Scopes[2]

 

console.dir은 객체의 내부 구조를 트리 형태로 펼쳐 보여주는 것이다. 이를 통해 함수 객체의 여러 프로퍼티들을 확인할 수 있는 것!

argument 프로퍼티

함수 객체의 argument 프로퍼티 값은 함수 호출 시 전달된 인수들의 정보를 담고 있는 argument 객체이다.

 

마치 배열 객체처럼 순회 가능하다는 특징을 가지고 있다. 하지만 진짜 배열은 아니기 때문에 map이나 forEach와 같은 배열 메서드를 직접 사용할 수는 없고 Array로 변환해야 한다.

 

선언된 매개변수의 개수보다 인수를 적게 전달했을 경우 인수가 전달되지 않은 매개변수는 undefined로 초기화된 상태이다.

function example(a, b) {
  console.log("a:", a);  // 첫 번째 인수
  console.log("b:", b);  // 두 번째 인수
  console.log("arguments:", arguments);  // 모든 인수 출력

  // arguments 객체 순회
  for (let i = 0; i < arguments.length; i++) {
    console.log(`arguments[${i}]:`, arguments[i]);
  }
}

// 3개의 인수를 전달했지만 매개변수는 2개만 선언됨
example(1, 2, 3);
a: 1
b: 2
arguments: [1, 2, 3]
arguments[0]: 1
arguments[1]: 2
arguments[2]: 3
  1. 매개변수 a, b에는 전달된 첫 번째, 두 번째 인수가 각각 할당됩니다.
  2. 초과된 인수(여기서는 3)는 무시되지 않고 arguments 객체에 모두 담깁니다.
  3. arguments 객체를 순회하여 모든 전달된 인수를 확인할 수 있습니다.

사용자 정의 프로퍼티 

function greet() {
  console.log("Hello!");
}
greet.language = "Korean";

console.dir(greet);
console.log(greet.language); // 출력: Korean

 

 

이 뿐만 아니라 [Scope] 같은 내부 정보도 확인 할 수 있기 때문에 클로저에 대해 이해하거나 디버깅 할 때 유용하다.

 

 

나머지 주요 프로퍼티

  • caller: 이 함수가 어디서 호출되었는지 참조한다. 현재 호출한 함수가 없을 경우 null.
  • length: 함수가 기대하는 매개변수의 개수를 나타낸다.
  • name: 함수의 이름을 반환한다.
  • prototype : 함수가 생성자 함수로 사용될 때 새로 생성된 객체에 연결되는 프로토 타입 객체를 말한다.
  • [Scopes] : 함수가 선언된 스코프 체인을 보여준다, 클로저를 사용한 경우 이 프로퍼티에서 클로저 내부 상태를 확인할 수 있다.

정리하자면, 함수는 일반 객체와 동일하게 다양한 프로퍼티를 가질 수 있으며, 객체로서도 여러 가지 활용이 가능하다는 점이 특징이다.

결론

자바스크립트에서 함수는 일급 객체이므로 다른 객체들과 마찬가지로 변수에 할당하거나 매개변수로 전달할 수 있으며, 런타임에서 동적으로 생성하고 조작할 수 있다. 이를 통해 유연하고 강력한 프로그래밍 패러다임을 활용할 수 있다.