본문 바로가기
프로그래밍 개발/JS ES6+

Javascript ES6+ Arrow Function

by Jinseok Kim 2020. 12. 11.
반응형

 

 

 

Arrow Function

 

 

 

var a = function () {
  return new Date()
}

var b = function (a) {
  return a * a
}

var c = function (a, b) {
  return a + b
}

var d = function (a, b) {
  console.log( a * b )
}

const f = funtion () {
  a: 1,
  b: 2
}

let a = () => new Date()

let b = a => a * a

let c = (a, b) => a + b

let d = (a, b) => {
  console.log( a * b )
}

const f = () => ({
  a: 1,
  b: 2
})

 

위와 같이 function()이라는 함수를 Arrow Function이라는 새로운 기능을 통해 더 직관적이고 간결하게 표현 할 수 있다.

 

Arrow Function을 쓸 때 아래와 같은 규칙이 있다.

 

 

1) (매개변수) => { 본문 }

2) 매개변수가 하나뿐인 경우 괄호 생략 가능

3) 매개변수가 없을 경우엔 괄호 필수

4) 본문이 `return [식 or 값]` 뿐인 경우 `{ }`와 `return` 키워드 생략 가능

5) 위 4) 에서 return할 값이 {}로 둘러싸인 `객체`인 경우엔 ()괄호 필수

 

 

 

 

 

 

 

 

 

Arrow Function와 this 바인딩

 

 

 

const obj = {
  a: function () {
    console.log(this)

    const b = () => {
      console.log(this)
    }

    b()
  }
}
obj.a()

//결과
//{a: ƒ}
//{a: ƒ}

 

  • 원래 변수 b의 함수안에서 있는 this는 언어 특성의 오류로 window 전역 객체를 가르켜 .call이나 .bind와 같은 메소드를 따로 주어 원하는 this 값을 가져와야 했다.
  • 하지만 위의 결과를 보고 알수 있듯이 Arrow Function을 쓰면서 함수 안의 this는 자동으로 외부 스코프의 this을 찾아와 쓰게 되었다.
  • 대신 Arrow Function을 쓴 함수안의 this는 바인딩을 할 수 없다는 특징을 가지고 있다.

 

 

 

응용

const obj = {
  grades: [80, 90, 100],
  getTotal: function () {
    this.total = 0
    this.grades.forEach(function(v) {
      this.total += v
    })
  }
}
obj.getTotal()
console.log(obj.total)

//결과:
//0

const obj = {
  grades: [80, 90, 100],
  getTotal: function () {
    this.total = 0
    this.grades.forEach(v => {
      this.total += v
    })
  }
}
obj.getTotal()
console.log(obj.total)

//결과:
//270

 

  • 위의 코드들 중 첫 번째 코드는 Arrow Function을 쓰지 않았다. 그래서 forEach 메소드의 첫 번째 인자인 콜백 함수안에 있는 this는 결국 window 전역객체를 가르킬 뿐이다. 그래서 forEach 메소드 특징을 이용하여 두 번째 인자에 this 넣어 원하는 this 값을 얻어내야하는 번거로움이 있다.
  • 하지만 두 번째 코드에서 Arrow Function을 콜백함수에 사용하였더니 자연스럽게 외부 스코프 this값을 가져와 원하는 결과 값을 얻어낸 것을 알 수 있다. 

 

 

 

 

Arrow Function와 바인딩 메소드 그리고 프로토타입

 

 

const a = () => {
  console.log(this)
}
a.call({a: 1})

//결과:
//window

하지만 위에서 언급한 것처럼 Arrow Function을 사용한 함수안의 this는 .call, .bind와 같은 바인딩이 먹혀들지 않는다.

 

 

 

 

근데 .call, .bind자체의 기능이 완전히 상실 된 것은 아니다.

const a = (...rest) => {
  console.log(this, rest)
}
a.call({a: 1}, 1, 2, 3)
//결과:
//window
//[1, 2, 3]

a.apply([], [4, 5, 6])
//결과:
//window
//[4, 5, 6]

const b = a.bind(null, 7, 8, 9, 10)
b()
//결과:
//window
//[7, 8, 9, 10]

 

※ .call, .bind 메소드의 특성은 첫 번째 인자를 this로 넘겨주는 것이고 두 번째 인자는 실행할 인자들로서 역할을 수행하고 있다.

 

  • 위의 결과들을 보면 this가 바인딩 되지 않아 window가 등장하기는 하지만 .call, .bind들의 두번째 인자부터의 본래 기능들은 무사히 실행되는 것을 확인 할 수 있다.
  • 즉 단지 .call, .bind 메소드의 첫 번째 인자의 바인딩 성능만이 되지 않는다는 것이다.

 

 

 

 

const P = (name) => {
  this.name = name
}
const j = new P('재남')

console.dir(P)

//결과:
//오류

 

  •  Arrow Function를 사용한 함수는 또 프로토타입이 사라져 새로운 생성 함수를 만들어 낼 수 없게 된다. 단지 자신의 함수로만 사용할 수 있게 되버린다.
  • 마치 메소드 함수를 간결하게 할때 간결하게 한 메소드는 생성 함수를 만들지 못하고 메소드로서만 존재할 수 있게 된 경우와 똑같은 예이다.
  • 위의 결과를 보면 새로운 생성 함수 P를 만들었지만 호출 결과는 오류이다.

 

 

 

응용하기 이해

const b = {
name: 'jin seok',
dd () {
return this.name;
},
a: x =>{
return this.name;
}
}
console.log(b.dd())
console.log(b.a())

//결과:
//"ji seok"
//"" (빈 객체를 가르킨다. 왜냐하면 비어있는 전역객체를 가르켰기 때문이다.)

 

  • 메소드 함수를  Arrow Function를 사용했다. 이때  Arrow Function을 적용한 함수안의 this는 window 전역객체를 가르킨다.
  • 왜냐하면 객체의 프로퍼티 값으로 메소드 함수가 되었다는 것은 즉 이 메소드 안의 this는 바인딩 되었다는 것이며  Arrow Function 특성상 this의 바인딩은 되지 않기 때문이다.

 

 

 

 

 

const b = {
name: "jin seok",
dd() {
const b=x=>{
return this.name;
}
console.log(b())
},
}
b.dd();

//결과
//"jin seok"

 

  • 대신 위의 코드처럼 Arrow Function를 내부 함수안에서 같은 this을 쓸때 유용하다고 볼 수 있다.

 

 

 

 

반응형

댓글