본문으로 건너뛰기
김신건의 로그

[Javascript] function

· 수정 · 📖 약 2분 · 996자/단어 #javascript #function #fundamentals
function, JavaScript function, JS function, 함수 선언, function declaration, function expression, 일반 함수

정의

function 은 JavaScript 에서 함수를 만드는 가장 기본적인 키워드. 호이스팅, this 동적 바인딩, arguments 객체, new 호출 등 arrow function 과 구분되는 고유한 특성을 가진다.

함수가 으로 다뤄지는 일급 함수 의 성질은 모든 형태에 공통.

사용 상황

상황권장 형태
객체 메서드 (this 가 객체를 가리켜야 함)function 선언/표현식
생성자 (new 와 함께)function 선언/표현식
prototype 메서드 추가function 표현식
재귀 함수이름 있는 함수 표현식 또는 선언문
콜백, 이벤트 핸들러 (this 불필요)화살표 함수 권장
짧은 단방향 변환화살표 함수 권장
호이스팅이 필요한 유틸 함수함수 선언문

두 가지 모양

함수 선언 (Function Declaration)

function greet(name) {
  return `Hello, ${name}`;
}
  • 호이스팅 됨 (선언 전 호출 가능)
  • 자기 이름 greet 으로 자신을 참조 가능 (재귀)

함수 표현식 (Function Expression)

const greet = function (name) {
  return `Hello, ${name}`;
};

// 이름 있는 함수 표현식 (named function expression)
const factorial = function fact(n) {
  return n <= 1 ? 1 : n * fact(n - 1);
};
  • 호이스팅 안 됨 (변수 선언만 호이스팅, 값은 평가 시점에 할당)
  • 익명 또는 이름 있음, 이름은 내부에서만 보임

호이스팅의 차이

greet('A'); // 'Hello, A', 함수 선언은 호이스팅
function greet(name) {
  return `Hello, ${name}`;
}

sayHi('B'); // TypeError: sayHi is not a function
const sayHi = function (name) {
  return `Hi, ${name}`;
};

함수 선언은 함수 자체 가 스코프 최상단으로 끌어올려진다. 표현식은 const/let/var 가 호이스팅되는 규칙을 따른다.

호이스팅 동작 시각화

JavaScript 엔진은 실행 전 코드를 두 단계로 처리한다.

flowchart TD
    A["소스 코드 파싱"]
    A --> B["1단계: 선언 수집"]
    B --> C["function 선언 전체를 스코프 최상단 등록"]
    B --> D["var 선언은 이름만 등록, 값 = undefined"]
    B --> E["let, const 는 TDZ 에 등록"]
    A --> F["2단계: 실행"]
    F --> G["라인 순서대로 값 할당 및 실행"]
    C --> H["어디서든 호출 가능"]
    D --> I["선언 전 접근 시 undefined"]
    E --> J["선언 전 접근 시 ReferenceError"]

function 선언은 1단계에서 함수 객체 전체 가 등록되므로 어디서든 호출 가능. 호이스팅 참고.

this 동적 바인딩

일반 함수의 가장 큰 특징. 호출 방식에 따라 this 가 결정된다.

호출 방식this
일반 호출 fn()undefined (strict) 또는 전역 객체
메서드 호출 obj.fn()obj
fn.call(ctx), fn.apply(ctx)ctx
fn.bind(ctx)()ctx
new fn()새 인스턴스
DOM 이벤트 리스너이벤트 타겟 (보통)
const obj = {
  name: 'Alice',
  greet() {
    console.log(this.name); // 'Alice'
  },
};

const fn = obj.greet;
fn(); // undefined, this 가 obj 가 아니다

이 “this 가 호출 시 결정” 특성이 arrow function 과 가장 큰 차이.

flowchart TD
    Call["함수 호출"]
    Call -->|"new fn()"| New["this = 새 인스턴스"]
    Call -->|"fn.call(ctx)"| Bind["this = ctx"]
    Call -->|"fn.bind(ctx)()"| Bind
    Call -->|"obj.fn()"| Method["this = obj"]
    Call -->|"fn() 직접 호출"| Direct["strict mode 여부"]
    Direct -->|"strict"| Undef["this = undefined"]
    Direct -->|"non-strict"| Global["this = 전역 객체"]

arguments 객체

일반 함수 안에는 arguments 라는 유사 배열 객체가 자동으로 존재.

function sum() {
  let total = 0;
  for (let i = 0; i < arguments.length; i++) {
    total += arguments[i];
  }
  return total;
}
sum(1, 2, 3); // 6

모던 코드에서는 ...rest 매개변수를 권장. arguments 는 배열이 아니라 유사 배열이라 .map 등이 안 통한다.

new 호출

생성자로 사용 가능. this 는 새 인스턴스를 가리킨다.

function Person(name) {
  this.name = name;
}
Person.prototype.greet = function () {
  return `Hello, ${this.name}`;
};

const p = new Person('Alice');
p.greet(); // 'Hello, Alice'

ES2015 class 문법이 이를 깔끔하게 대체. 그래도 내부적으로는 같은 메커니즘.

프로토타입 체인

일반 함수는 prototype 속성을 가진다 (생성자로 쓰일 수 있어서).

function Animal() {}
Animal.prototype.eat = function () { /* ... */ };

const dog = new Animal();
dog.eat(); // 프로토타입 체인을 따라 찾음

arrow functionprototype 이 없어 new 호출 불가.

일반 함수 vs 화살표 함수 비교

특성function() => {}
this호출 시 결정 (동적)정의 시 결정 (lexical)
arguments✗ (rest 사용)
new 호출✓ (생성자 가능)✗ (TypeError)
prototype
호이스팅 (선언문)✗ (표현식만 가능)
짧은 문법
메서드로 적합△ (this 가 lexical 이라서)

자세한 화살표 함수 동작은 arrow function 참고.

고급 패턴

IIFE (즉시 실행 함수)

(function () {
  // 즉시 실행, 전역 스코프 오염 방지
  const secret = 'hidden';
  console.log(secret);
})();

모듈 시스템이 없던 시절 스코프를 격리하는 패턴. 현재는 ES Modules 가 대체.

커링 (Currying)

function multiply(a) {
  return function (b) {
    return a * b;
  };
}
const double = multiply(2);
double(5);  // 10
double(10); // 20

인자를 하나씩 받는 함수 연쇄. 클로저a 를 기억한다.

메모이제이션

function memoize(fn) {
  const cache = new Map();
  return function (...args) {
    const key = JSON.stringify(args);
    if (cache.has(key)) return cache.get(key);
    const result = fn.apply(this, args);
    cache.set(key, result);
    return result;
  };
}

const fib = memoize(function (n) {
  return n <= 1 ? n : fib(n - 1) + fib(n - 2);
});

언제 일반 함수를 쓰는가

  • 객체의 메서드, this 가 객체를 가리켜야 함
  • 생성자, new 와 함께
  • prototype 메서드, 클래스 메서드
  • 재귀 함수 (이름 있는 표현식 또는 선언문)

함정

1. 메서드를 변수에 꺼내면 this 잃음

const timer = {
  tick: 0,
  increment() {
    this.tick++;
  },
};

const inc = timer.increment;
inc();              // this = undefined (strict) 또는 전역
inc.call(timer);    // this = timer (해결)

// 또는 bind 로 고정
const boundInc = timer.increment.bind(timer);
boundInc();         // 항상 timer

2. var 호이스팅과 함수 선언이 같은 이름

console.log(typeof foo);   // 'function'
var foo = 'bar';
function foo() {}
// 함수 선언이 var 보다 우선 (호이스팅 순서)

3. arguments 는 배열이 아님

function f() {
  arguments.map(x => x * 2);      // TypeError: arguments.map is not a function
  [...arguments].map(x => x * 2); // ✓ 배열로 변환
}

// 권장: rest 파라미터 사용
function g(...args) {
  args.map(x => x * 2); // ✓
}

4. 화살표 함수를 메서드로 쓰면 this 가 전역

const obj = {
  name: 'Alice',
  greet: () => {
    console.log(this.name); // undefined (lexical this = 전역)
  },
};
obj.greet(); // 의도와 다름

관련 위키

이 글의 용어 (8개)
[Javascript] 클로저javascript
정의 클로저 (Closure): 함수가 자신이 정의된 시점의 외부 변수들을 계속 참조할 수 있는 성질. 함수가 일급 객체 () 인 언어의 자연스러운 결과. 메커니즘은 + 함수 객…
[Javascript] 호이스팅 (Hoisting)javascript
정의 호이스팅 (Hoisting) 은 JavaScript 엔진이 코드를 실행하기 전 바인딩 생성 단계 에서 스코프 내의 선언을 파악하고 등록하는 메커니즘이다. 마치 선언이 스코프…
[Javascript] Arrow Functionjavascript
정의 화살표 함수 (arrow function) 는 ES2015 (ES6) 에서 도입된 함수 표현식. 모양. 더 짧은 문법뿐 아니라 가 lexical 로 바인딩 되는 본질적 차이…
[Javascript] Lexical Environmentjavascript
정의 Lexical Environment (어휘적 환경) 는 ECMAScript 명세 (§9.1) 가 정의한 내부 객체. 함수가 호출될 때마다 새로 만들어지며, 이 호출의 변수들…
[Javascript] Prototype Chainjavascript
정의 JavaScript 의 모든 객체는 (내부 슬롯) 을 가진다. 속성 lookup 시 자신에게 없으면 prototype chain 을 따라 올라가며 검색. 접근 함수의 pro…
[Javascript] this 바인딩javascript
정의 JavaScript 의 는 호출 방식에 따라 결정 되는 동적 바인딩. 4 가지 호출 방식 + arrow function (lexical) 규칙. 5 가지 규칙 | # | 규…
고차 함수javascript
정의 고차 함수 (Higher-Order Function, HOF): 다음 조건 중 하나 이상을 만족하는 함수. 1. 함수를 인자로 받는다. 2. 함수를 반환한다. 특성이 있어야…
일급 함수javascript
정의 일급 함수 (First-Class Function): 함수를 숫자, 문자열, 객체처럼 값으로 다룰 수 있는 언어의 특성. 다음 세 가지가 모두 가능하면 그 언어의 함수는 일…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기