Javascript - 화살표 함수(Arrow Functions)

자바스크립트에서 함수를 생성하기 위해서는 주로 function 키워드를 사용합니다.

function 키워드는 2가지 방법으로 함수를 생성할 수 있는데요, 

// 함수 선언(Function Declaration)
function sayHi(){ 
  console.log("hi!");
}

// 함수 표현(Function Expression)
var sayHi2 = function(){
  console.log("hi!");
};

이 중 함수 표현은 무명(anonymous:이름이 없음) 함수를 생성한 후 변수에 담는 방식입니다.
이 함수 표현 방법으로 함수를 생성할 때 화살표 함수를 사용하여 함수를 생성할 수 있습니다.
위 sayHi2를 화살표 함수로 생성하면 아래와 같습니다.

var sayHi2 = () => console.log("hi!");

이와 같이 화살표 함수는 무명 함수를 생성하는 방법 중의 하나로 기본 형태는  (파라메터1, 파라메터2,...) => { 함수내용 }입니다.

화살표 함수의 형태상 특징은 다음과 같습니다.

  1. 함수 내용이 한줄인 경우 함수내용을 감싸는 {}를 사용하지 않아도 됩니다.
  2.  {}가 없는 경우 해당 함수의 실행결과를 자동으로 이천 합니다.
  3. 함수 내용이 한줄 이상인 경우 return을 사용해서 결과를 리턴합니다.
  4. 파라메터가 한개인 경우 파라메터를 감싸는 ()를 생략할 수 있습니다. (파라메터가 없는 경우에는 위의 sayHi2의 경우 처럼 파라메터 없이 빈 ()를 표시하여야 합니다.)

위 내용을 사용해서 함수 표현과 화살표 함수를 비교해 봅시다.

// 함수 표현
filteredArray = myArray.filter(function(element){
  return element > 2;
});

// 화살표 함수
filteredArray = myArray.filter(element => element > 2);

동일한 역할을 하는 코드지만 화살표 함수로 더 깔끔합니다.

화살표함수는 단순히 코드 수를 줄이는 역할 뿐만 아니라 일반 함수와 비교하여 this가 바인딩하지 않는다는 기능상의 차이도 있습니다.

var myObj = { 
  myText: "hi!",
  myFunc: function(){
    setTimeout(function(){
      console.log(this.myText);
    }, 1000)
  },
  myFunc2: function(){
    setTimeout(()=>console.log(this.myText), 1000);
  }
};

myObj.myFunc(); // undefined
myObj.myFunc2(); // "hi!"
위 예제에서 myFunc의 경우 setTimeout의 callback으로 function으로 생성된 무명 함수가 들어갑니다. 이 경우에 this는 새로 생성된 무명함수가 되어 this.myText는 undefined가 됩니다. 하지만 myFunc2처럼 화살표 함수를 사용하면 this는 그대로 myObj로 남게 되고 myObj.myText 역시 "hi!"로 남게 됩니다. 이처럼 객체에서 무명 함수를 callback으로 사용하는 경우this로 인해 헷갈리는 부분이 줄어들게 되었습니다.

댓글

H
Hyunjung Ji 2018.03.27
이건 무식한 질문 같긴 한데요.(쭈뼛..) 바인딩이 묶는다는 뜻이라면 myFunc2의 this가 오히려 바인딩 하는거 아닌가 궁금해요.  myFunc2의 this가 myObj를 받아서 "hi!"를 출력하는거니까 바인딩 하는게 아닌가유?;;;;
myFunc의 this가 undefined 되는 이유는 익명함수로 감싸져서 그런가요? ; ㅁ ;
I
Ian H 2018.03.27
@Hyunjung Ji,
화살표 함수를 사용한 myFunc2()의 경우 this.myText가 제대로 표시되니까 this가 바인딩된 것이고, callback 함수를 사용한 myFunc()의 경우 this.myText가 안나오니까 this가 바인딩이 안된 것이라고 생각할 수도 있겠네요. 충분히 의문을 가질 수 있는 질문이라고 생각됩니다.
좀 더 자세히 설명하자면 이 현상은 스코프(scope)때문인데요, myFunc2(화살표 함수)의 경우 this가 바인딩되지 않아 상위 스코프(myObj)의 this를 가져와 this.myText가 나온 것이고 myFunc(callback 함수)의 경우 자체적으로 this가 바인딩되어 자신의 스코프 내의 this을 가져와 this.myText가 undefined된 것입니다. 
콜백으로 호출하지않고 object에 바로 일반함수와 화살표 함수를 사용하면 아래와 같은 결과가 나옵니다.
var myObj = {    myFunc: function(){ console.log(this);  },   myArrowFunc: ()=>console.log(this), };
myObj.myFunc() // {myFunc: ƒ, myArrowFunc: ƒ} myObj.myArrowFunc() // Window {postMessage: ƒ, blur: ƒ, …}
myFunc과 myArrowFunc은 모두 myObj 오브젝트의 property입니다.
myFunc은 함수 표현으로 무명함수가 할당되어 있는 상태입니다. myObj.myFunc()를 실행하면 해당 함수의 오브젝트인 myObj의 this가 바인딩되어 myObj가 출력됩니다.
myArrowFunc은 화살표 함수가 할당되어 있습니다. myObj.myArrowFunc()를 실행하면  myObj의 this가 바인딩되지 않기 때문에 상위 스코프인 Window 오브젝트가 출력됩니다.
I
Ian H 2018.03.27
처음부터 이렇게 설명하지 않고 콜백을 써서 설명한 이유는 화살표 함수를 쓰는 가장 큰 이유 중 하나가 콜백으로 사용하여 해당 오브젝트의 this를 받아 쓰는 것이기 때문입니다.
일반함수를 써서 이 문제를 해결하려면
var myObj = {    myText: "hi!",   myFunc: function(){     var self = this;     setTimeout(function(){       console.log(self.myText);     }, 1000)   } };
이렇게 변수를 선언하고 해당 변수를 사용해 줘야 되는데, 화살표 함수를 사용하면 아래처럼 간단하게 해결할 수 있죠.
var myObj = {    myText: "hi!",   myArrowFunc: function(){     setTimeout(()=>console.log(this.myText), 1000);   } };
중요한 질문을 해주셔서 감사합니다!
H
Hyunjung Ji 2018.03.28
아~~~~ 익명함수가 콜백함수에서 빛을 발하는군요.. ' ㅁ ' 리액트에서도 화살표함수가 주로 쓰인다기에, 제대로 알고 싶었거든요.. 근데 화살표 함수에서의 this의 역할이 너무 이해가 안되는거예요.  Ian H님 덕분에 눈에 비늘이 벗져진 느낌입니다요. 감사합니다. 흑흑.....
H
Hyunjung Ji 2018.03.28
아하~~ 예제로 설명해주시니까 확 이해가 됐어요!! 정말 감사합니다!! 익명함수에서 this가 let 이라면, 화살표 함수의 this는 var 같은 건가봐요.. (아닌가 헤헤.. 스코프는 쉬운것 같은데 맨날 헷갈려요 ㅋㅋ)  암튼 친절한 설명 너무 감사해요.  감동 받았어유 !!!^____^/
I
Ian H 2018.03.30
@Hyunjung Ji,
저도 한번도 반대로 생각해 본적이 없었는데 다른 관점에서 생각해 볼 수 있어서 좋았습니다.
좋은 질문 해 주셔서 감사합니다^^
댓글쓰기

이 글에 댓글을 다시려면 SNS 계정으로 로그인하세요. 자세히 알아보기

UP