[JavaScript] 화살표 함수와 this, bind()

wha1e·2025년 1월 7일
1

TIL

목록 보기
5/8


📍화살표 함수란?

An arrow function expression is a compact alternative to a traditional function expressions, with some semantic differences and deliberate limitations in usage:

화살표 함수 표현식(화살표 함수 expression)은 함수 표현식에 대한 간결한 대안으로, 약간의 의미적 차이와 의도적인 사용상의 제한을 가지고 있습니다.

화살표 함수는 ES6에 새롭게 나온 함수의 새로운 형태로, 기존의 function 키워드보다 간략하게 함수를 선언할 수 있다.

화살표 함수의 이름은 문법에서 볼 수 있는 때문으로, 화살의 생김새와 비슷하여 네이밍되었다.

화살표 함수는 C++, Python, Java등 다양한 언어에서 사용하는 람다 함수(lambda function)의 아이디어를 자바스크립트 문법으로 표현했다. 이를 통해 함수형 프로그래밍 스타일을 더욱 강화하고, 코드를 더 간결하고 가독성 좋게 작성하도록 발전시킨 형태라고 볼 수 있다.

(1) 화살표 함수의 선언

// 매개 변수 지정 방법
(매개변수) => { ... }

// 함수 몸체 지정 방법
x => { return x }
x => x //함수의 몸체가 한줄의 구문이라면 중괄호를 생략할 수 있다. 암묵적으로 return 된다.

(2) 화살표 함수의 호출

화살표 함수는 익명 함수로만 사용할 수 있다. 따라서, 화살표 함수를 호출하는 과정에서는 함수 표현식을 사용해야 한다.

ES5와의 차이는 아래와 같다.

//ES5
var pow = function (x) { return x * x; };
console.log(pow(10)); // 100

// ES6
const pow = x => x * x;
console.log(pow(10)); // 100

화살표 함수는 콜백 함수로 사용할 때 편리하게 간소화하여 사용할 수 있는데, 대표적으로는 map 함수에서 편리하게 사용할 수 있다.

// ES5
var arr = [1, 2, 3];
var pow = arr.map(function (x) { // x는 요소값
  return x * x;
});

console.log(pow); // [ 1, 4, 9 ]

// ES6
const arr = [1, 2, 3];
const pow = arr.map(x => x * x);

console.log(pow); // [ 1, 4, 9 ]

화살표 함수에 대해서 조금 더 알기 전에 this와 bind에 대해 알아보고 다이브해보자.


📍this란 무엇인가?

  • 화살표 함수에는 자체 바인딩이 this에 없으며, 인수 또는 super로 사용해야 하며, 메서드로 사용하면 안 됩니다. (화살표 함수의 제한점 1)

화살표 함수는 부모 객체this를 상속받아 사용한다는 중요한 특징이 존재한다.

그렇다면 this는 무엇일까?

this는 객체지향 프로그래밍을 적용하기 위해 나온 기능으로 this는 내가 있는 객체를 의미한다. 이 때, this는 함수가 호출될 때 결정 된다.

const person = {
	name: "Whale",
	getName: function () {
		console.log("person getName", this);
	},
};

실행 결과

이 상태로 this를 호출하게 되면, 현재 호출하고 있는 위치인 person 객체를 가져오게 된다.

만약, 특정 스코프 안이 아닌, 객체 밖에서 호출하게 되면 어떻게 될까?

const person = {
	name: "Whale",
	getName: function () {
		console.log("person getName", this);
	},
};

const globalPerson = person.getName;
globalPerson();

실행 결과


뜬금없이 window 객체를 가져오게 된다. this는 호출할 때의 객체를 기준으로 따지게 되며, 어디에서 호출했는지에 따라 결정되기 때문이다.

person 객체를 통해 실행한 것이 아니라, 익명 함수를 선언하고 Global에서 실행을 했기 때문에, 호출한 위치이자 객체인 Window를 가져오게 된 것이다.

그렇다면, 화살표 함수가 부모 객체의 this를 상속받아 사용한다는 것은 어떤 의미일까?

const person = {
  name: 'Whale',
  getName: function () {
    console.log('person getName', this);
    const innerFunc = function () {
      console.log('innerFunc', this);
    };
    //ES5 일반 함수
    innerFunc();
  },
};

person.getName();

실행 결과

여기서 확인해보면, innerFunc이 뜬금없이 Window 객체를 반환한 것을 볼 수 있다.

그 이유는 innerFunc() 을 호출할 때, 앞에 person.innerFunc()과 같이 호출하는 객체를 지정하지 않았기 때문에, 이 또한 Window 객체가 반환된 것이다.

위와 같이 함수의 중첩 과정에서 this의 추적이 어렵고 관리가 복잡한 경우에 사용할 수 있는 방법이 두 가지 존재한다.


📍첫 번째 방법 bind()

The bind() method of Function instances creates a new function that, when called, calls this function with its this keyword set to the provided value, and a given sequence of arguments preceding any provided when the new function is called.

bind() 메소드가 호출되면 새로운 함수를 생성합니다. 받게되는 첫 인자의 value로는 this 키워드를 설정하고, 이어지는 인자들은 바인드된 함수의 인수에 제공됩니다.

bind는 this로 설정할 객체를 설정할 수 있는 기능으로, 시시각각 바뀌는 this를 편리하게 관리할 수 있다.

const person = {
  name: 'Whale',
  getName: function () {
    console.log('person getName', this);
    const innerFunc = function () {
      console.log('innerFunc', this); // this는 person 객체
    }.bind(person); // this를 person으로 바인딩

    innerFunc();
  },
};

person.getName();

실행 결과

위와 같이, innerFunc에 person 객체 혹은 this를 바인딩하면, 해당 함수를 호출할 때에는 반드시 person을 부르게 되어, 원하는 객체를 올바르게 사용할 수 있다.

위의 방식은 ES6 이전의 일반 함수 형태로 작성할 때 유효한 방식이며, bind()를 사용할 때에는 일반 함수를 사용하길 권장하고 있다.


📍두 번째 방법 화살표 함수

첫 번째 방법을 보면 생각보다 복잡한 형태로 구성되어 있어, 가독성이 떨어지는 것을 알 수 있다.

bind를 사용하지 않고, 단순하게 화살표 함수를 이용하면 아래와 같이 구성할 수 있다.

const person = {
  name: 'Whale',
  getName: function () {
    console.log('person getName', this);
    const innerFunc = () => console.log('innerFunc', this);
    innerFunc();
  },
};

person.getName();

실행 결과

첫 번째 방법 보다 훨씬 간결하게 표현이 가능한 것을 볼 수 있다.

이것이 가능한 이유는 화살표 함수가 자신만의 this를 갖지 않기 때문이다. 화살표 함수를 사용할 때 편리하게 적용할 수 있는 특징이자, 반드시 알아두어야 하는 개념이다.


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

  1. 화살표 함수는 인스턴트를 생성할 수 없습니다. 즉, 생성자 함수로 사용할 수 없습니다.
  2. 화살표 함수는 자신만의 this를 가지지 않습니다.
  3. 화살표 함수는 arguments 객체를 가지지 않습니다.

MDN에서는 클래스로 사용하는 다양한 요소를 다루고 있는데, 알고 넘어가야 하는 꼭 필요한 세 가지만 살펴보자.

1. 화살표 함수는 인스턴트를 생성할 수 없습니다. 즉, 생성자 함수로 사용할 수 없습니다.

const Person = (name) => {
this.name = name;
};

const john =new Person("John"); // 에러 발생: Person is not a constructor

화살표 함수는 일반 함수와 달리 인스턴트를 생성할 수 없다. non-constructor이기 때문입니다. 그렇기 때문에 prototype 속성이 없고, 프로토타입도 생성하지 않는다.

2. 화살표 함수는 자신만의 this를 가지지 않습니다.

📍두 번째 방법 화살표 함수 에서 설명한 내용으로, 화살표 함수의 특징이다.

3. 화살표 함수는 arguments 객체를 가지지 않습니다.

function outerFunc() {
  const arrowFunc = () => {
    console.log(arguments); // 상위 함수의 arguments 참조
  };
  arrowFunc(4, 5, 6);
}

outerFunc(1, 2, 3); // [1, 2, 3]

실행 결과

arguments 객체는 함수 안에서 인수에 접근하는데 사용된다. 일반 함수에서는 이 객체를 사용할 수 있지만, 화살표 함수에서는 자신만의 arguments 를 갖지 않는다.

따라서, arguments를 사용하고자 한다면, 일반 함수를 이용하여 선언하고 사용해야 한다.


참고 자료

https://www.youtube.com/watch?v=tDZROpAdJ9w

https://poiemaweb.com/es6-arrow-function

https://ko.javascript.info/arrow-functions-basics

https://codingeverybody.kr/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%99%94%EC%82%B4%ED%91%9C-%ED%95%A8%EC%88%98%EC%9D%98-%EC%9D%B4%ED%95%B4%EC%99%80-%EC%82%AC%EC%9A%A9%EB%B2%95/

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/Arrow_functions

profile
상상을 현실로 만드는 FE

0개의 댓글

관련 채용 정보