개발자공부일기

Arrow Function(화살표 함수) 본문

Language/Javascript

Arrow Function(화살표 함수)

JavaCPP 2025. 10. 27. 17:42

 

────────────────

1.화살표 함수(Arrow Function)란?

────────────────

화살표 함수는 ES6에서 추가된 새로운 함수 문법이다.

기본 형태

const add = (a, b) => {
  return a + b;
};

조금 더 줄이면

const add = (a, b) => a + b; // 한 줄이면 return 생략 가능

매개변수가 하나면 괄호도 생략 가능

const square = x => x * x;

객체를 바로 반환할 때는 소괄호로 감싸야 한다

const makeUser = (name, age) => ({ name, age });

여기서 객체를 반환할때 소괄호를 쓰는 이유는 {}만 있으면 이게 로직을 감싼건지 객체인지 구별하지 못하기 때문이다.

 

────────────────
2. this와 화살표 함수
────────────────

우리가 일반 함수를 쓸 때는, 그 함수가 "어디서 호출되느냐"에 따라 this 값이 달라진다고 배웠다.

예를 들어 객체 안에서 메서드로 호출하면 그 메서드 안의 this는 그 객체를 가리킨다.

const obj = {
  say() {
    console.log(this);
  }
};

obj.say(); // this === obj

즉 일반 함수(또는 메서드 형태로 선언된 함수)는 호출 주체(obj.say()의 obj)에 따라 this가 정해진다.

그런데 화살표 함수는 이 규칙을 따르지 않는다.

화살표 함수는 자기만의 this를 만들지 않는다.
대신 "바깥에 있던 this"를 그냥 가져와서 쓴다.

이걸 lexical this(렉시컬 this)라고 부른다.
쉽게 말하면

"화살표 함수 안에서의 this는, 그 화살표 함수가 선언된 위치의 this를 그대로 따라간다.
호출 방식으로 바뀌지 않는다."

라고 생각하면 된다.

 

코드 1: 일반 함수 버전

const object1 = {
  A: function () { console.log(this); }
};

object1.A();

// 출력결과: object1

설명:

  • A는 일반 함수다.
  • object1.A() 형태로 호출했기 때문에,
    이때의 this는 object1을 가리킨다.
  • 그래서 console.log(this)는 object1이 찍힌다.

이건 우리가 흔히 알고 있는 동작이다.
"객체에서 메서드를 호출하면 this는 그 객체다" 라는 기본 규칙.

코드 2: 화살표 함수 버전

const object2 = {
  A: () => { console.log(this); }
};

object2.A();

// 출력결과: window (브라우저 기준)

여기서 왜 window가 찍힐까?


화살표 함수는 자기 this가 없고,
"선언된 순간의 바깥 this"를 그냥 써버린다고 했다.

지금 이 화살표 함수 A: () => { ... } 는 어디에서 선언됐나?
전역 컨텍스트(스크립트의 최상위 레벨) 안에서 선언된 거랑 다를 바가 없다.

브라우저의 전역 컨텍스트에서 this는 window를 가리킨다.
즉 바깥 this가 이미 window인 상태에서 함수가 만들어진 것.

그래서 object2.A() 라고 호출해도,
"object2가 this가 되지 않음".
왜냐면 화살표 함수는 호출 방식으로 this를 다시 설정하지 않기 때문.

정리해서 말하면:

  • 일반 함수: 실행할 때 누가 나를 불렀냐(object2.A()에서 object2)로 this 결정
  • 화살표 함수: 실행할 때 누가 부르든 상관없이, 만들 당시의 바깥 this(window 등)를 그대로 사용

────────────────
3. 이게 왜 항상 장점은 아닌가?
────────────────

많은 사람들이 "화살표 함수 쓰면 this 문제 안 나서 좋다"라고만 외우는데, 그건 절반만 맞는 말이다.

장점인 경우:
비동기 콜백처럼 this가 자꾸 날아가던 상황에서 this를 고정하고 싶을 때

예:

const counter = {
  value: 0,
  inc() {
    setTimeout(() => {
      this.value++;
      console.log(this.value);
    }, 100);
  }
};

counter.inc(); // 1

여기서 setTimeout 안의 콜백은 화살표 함수다.
이 화살표 함수의 this는 바깥 inc() 메서드의 this와 동일하다.
inc()는 counter.inc()로 호출되므로 this === counter.
→ 그래서 this.value가 counter.value를 잘 가리킨다.
→ 이런 상황에선 화살표 함수가 매우 편하다.

 

단점이 되는 경우:
객체의 메서드를 화살표 함수로 정의했는데,
그 안에서 this가 그 객체를 가리키길 기대했다면 실망하게 된다.

const object2 = {
  A: () => { console.log(this); }
};

object2.A(); // window

우린 "object2의 메서드니까 this는 object2겠지?"라고 기대했는데
화살표 함수는 그런 식으로 동작하지 않는다.
그냥 (정확히 말하면) 전역 this를 캡처한 상태인 거다.

즉 "화살표 함수를 메서드로 쓰면, 내가 원하는 this가 아닐 수 있다."

한 줄 요약:
화살표 함수는 바깥 this를 그대로 고정하기 때문에 편할 때도 많지만,
반대로 말하면 "이 메서드 안의 this가 이 객체 자신이길 원한다" 같은 경우에는 오히려 문제가 될 수 있다.

────────────────
4. 그래서 화살표 함수는 언제 쓰고, 언제 안 쓰나?
────────────────

좋은 사용 위치

  • 콜백 (setTimeout, setInterval, Promise.then, map/filter/reduce 등)
  • 간단한 유틸 함수 (값 계산, 변환 등)
  • 클래스/객체 메서드 내부에서 내부 콜백에 넘기는 용도 (this 보존용)

조심해야 할 위치

  • 객체의 메서드를 정의할 때 그 안에서 this를 그 객체로 쓰고 싶을 때
  • DOM 이벤트 핸들러에서 this가 클릭된 요소를 가리켜야 하는 코드

예를 들어 DOM 이벤트 핸들러 비교:

button.addEventListener("click", function () {
  console.log(this); // 클릭된 button
});

button.addEventListener("click", () => {
  console.log(this); // button 아님. 외부 this를 그대로 사용
});

────────────────
5. 정리
────────────────

사용시 생각해야 할 것:
우리는 일반 함수일 때는 함수가 어떻게 호출되느냐에 따라 this가 달라진다고 알고 있다.
object1.A()처럼 부르면 this는 object1이 된다.

하지만 화살표 함수는 어디서 어떻게 호출하든 내부의 this를 새로 만들지 않는다.
화살표 함수는 "자신이 선언될 당시 바깥에 있던 this"를 그냥 그대로 쓴다.

그래서 이런 코드에서

const object1 ={
  A : function(){ console.log(this) }
};
object1.A();
// 출력: object1

const object2 ={
  A : () => { console.log(this) }
};
object2.A();
// 출력: window (브라우저 기준)

이런 차이가 나온다.

왜 window가 나오냐?
→ 화살표 함수 A는 object2의 this를 만들지 않고,
전역 범위(브라우저에선 window)의 this를 캡처해서 그대로 쓰기 때문이다.

이 특징은 상황에 따라 장점이 될 수도 있고 단점이 될 수도 있다.

  • 장점: 콜백 안에서 this를 safe하게 유지할 수 있다 (setTimeout 예제처럼).
  • 단점: 어떤 객체의 메서드에서 그 객체 자신을 this로 쓰고 싶었는데, 화살표 함수를 써버리면 전혀 다른 this(window 등)가 찍혀버린다.

'Language > Javascript' 카테고리의 다른 글

Express  (0) 2025.10.28
Next.js에서 Node.js와 Edge환경  (0) 2025.08.01
Node.js의 Libuv 라이브러리  (0) 2025.02.26
Node.js의 이벤트 루프  (0) 2025.02.20
JWT  (0) 2025.02.11