Javascript 일반함수와 ES6 화살표 함수

유다송·2023년 8월 6일
0

JavaScript

목록 보기
5/8
post-thumbnail

자바스크립트 this

  • this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수다. this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다.
  • 일반적으로 객체 지향 언어에서 this라는 예약어는 함수가 속해 있는 객체 자기 자신과 굉장히 관련이 깊다. 이러한 사실을 통해 우리는 자바스크립트도 얼추 비슷한 의미겠구나 하고 조심스럽게 예측할 수 있다. 그러나 자바스크립트에는 자기 자신이라는 말이 상당히 모호하다.

자바스크립트의 함수

  • 변수나 데이터에 할당할 수 있습니다.
  • 다른 함수의 인수로 전달할 수 있습니다.
  • 함수의 반환 값으로 사용 가능합니다.

함수가 선언된 이후에 어떤 환경에서 어떤 객체에 의해 호출되지 예측할 수가 없기 때문에 자바스크립트 함수에서 자기 자신이라는 표현을 사용하는게 엄청 까다로운 일이다.

자바스크립트에서 모든 함수는 this를 가지고 있다. 그리고 함수가 호출 되면 그때 그때 상황에 따라 this가 가리키는 객체가 결정된다. 이렇게 함수가 호출 될 때마다 this가 동적으로 결정되는 것을 "this가 그 객체에 binding 된다"라고 표현한다.

일반 함수의 바인딩 방식

console.log(this); // (1) window

const a = {
  name: "realzu",
  getName() {
    console.log(this);
  }
}

a.getName(); // (2) { name: 'realzu', getName: ƒ getName() }

const b = a.getName;
b(); // (3) window

그렇다면 왜 화살표 함수를 쓸까?

자바스크립트에서 함수를 사용하는 이유

  • 여러가지 기능을 하는 코드를 한 단어로 묶고 싶을 때 (그리고 나중에 재사용할 때)
  • 입출력기능을 만들 때

화살표 함수 (Arrow Function)

  • 함수 본연의 입출력기능을 아주 직관적으로 잘 표현해준다.
  • 소괄호, 중괄호 생략이 가능하다.
  • 내부에서 this값을 쓸 때 밖에 있던 this값을 그대로 사용한다. 즉 당시에 의존하는 기존의 binding 규칙은 화살표 함수 안에서 this에게 전혀 영향을 끼치지 않는다.

화살표 함수와 일반 함수의 차이

1. 화살표 함수는 인스턴스를 생성할 수 없는 non-constructor 이다

const Foo () => {};

new Foo(); // TypeError: Foo is not a constructor
  • prototype 프로퍼티가 없고 프로토타입도 생성하지 않는다
const Foo () => {};

Foo.hasOwnProperty('prototype'); // false

2. 화살표 함수는 중복된 매개변수 이름을 선언할 수 없다. 일반 함수는 중복되는 매개변수 이름을 선언할 수 있다.

일반함수

function normal(a, a) {return a + a;}
console.log(normal(1, 2)); // 4

function normal(a, a, a) {return a + a;}
console.log(normal(1, 2, 3)); // 6

화살표 함수

const arrow = (a, a) => a + a;
// SyntaxError:  Duplicate parameter name not allowed in this context

3. 화살표 함수는 함수 자체의 this, arguments, super, new.target 바인딩을 갖지 않는다.

일반함수

const cat = {
  name: 'meow',
  foo1: function() {
    const foo2 = function() {
      console.log(this.name);
    }
    foo2();
  }
};

cat.foo1();	// undefined
  • cat.foo1() 메소드 호출 시 내부 함수 foo2가 실행됨
  • 함수가 호출됐으므로 foo2 내부의 this는 지정되지 않아서 곧 전역 객체를 가리킴
  • 전역 객체에 name이란 속성은 존재하지 않으므로 undefined가 뜸

화살표 함수

const cat = {
  name: 'meow',
  foo1: function() {
    const foo2 = () => {
      console.log(this.name);
    }
    foo2();
  }
};

cat.foo1();	// meow
  • JavaScript에서는 어떤 식별자(변수)를 찾을 때 현재 환경에서 그 변수가 없으면 바로 상위 환경을 검색한다. 그렇게 점점 상위 환경으로 타고 타고 올라가다가 변수를 찾거나 가장 상위 환경에 도달하면 그만두게 되는 것.
  • 화살표 함수에는 this라는 변수 자체가 존재하지 않기 때문에 그 상위 환경에서의 this를 참조하게 된다.
  • function으로 선언한 함수가 메소드로 호출되냐 함수 자체로 호출되냐에 따라 동적으로 this가 바인딩되는 반면, 화살표 함수는 선언될 시점에서의 상위 스코프가 this로 바인딩된다.

화살표 함수를 어떨 때 사용하면 안될까?

addEventListener()의 콜백함수

const button = document.getElementById('myButton');

button.addEventListener('click', () => {
  console.log(this);	// Window
  this.innerHTML = 'clicked';
});

button.addEventListener('click', function() {
   console.log(this);	// button 엘리먼트
   this.innerHTML = 'clicked';
});

원래 addEventListener의 콜백함수에서는 this에 해당 이벤트 리스너가 호출된 엘리먼트가 바인딩되도록 정의되어 있다. 이처럼 이미 this의 값이 정해져있는 콜백함수의 경우, 화살표 함수를 사용하면 기존 바인딩 값이 사라지고 상위 스코프(이 경우엔 전역 객체)가 바인딩되기 때문에 의도했던대로 동작하지 않을 수 있다. 물론 상위 스코프의 속성들을 쓰려고 의도한 경우라면 사용할 수 있다.

[JavaScript] 화살표 함수와 this 바인딩
[JavaScript] This (바인딩 룰, 화살표 함수)
화살표 함수
ES6 In Depth: Arrow functions

0개의 댓글