[JS] #2 Arrow Function

개요

const add = function(one, two) {
  return one + two;
};
console.log(add(1, 2));
const total = (one, two) => {
  return one + two;
};
console.log(total(1, 2));
// 3
// 3
  • 코드 형태
    (param) => { 함수 코드 }
  • function (){ }의 축약 형태이지만 고려할 사항도 있습니다
    • this 참조가 다릅니다.

함수 블록 사용

const total = (one, two) => one + two;
console.log(total(1, 2));
// 3

화살표 함수에서 함수 블록과 return 작성을 생략할 수도 있습니다.
⇒ 파라미터 값이 1개일 경우 괄호도 생략 가능합니다.

const total = (one) => { };
console.log(total(1)); 
// undefined

함수 블록{ }만 작성한 형태

const point = (param) => ({book: param});
const result = point("책");
for(const key in result){
  console.log(key + ": "+result[key]);
};
// book: 책

{key: value}를 반환하는 형태
⇒ {key: value}를 소괄호로 감싸면 {key: value}를 반환합니다. 만약 소괄호를 작성하지 않는다면 undefined를 반환합니다.

파라미터 사용

const get = param => param + 20;
console.log(get(10)); 
// 30

파라미터가 하나일 경우

const get = () => 10 + 20;
console.log(get());
// 30

파라미터가 없으면 소괄호만 작성합니다.


함수 구조

화살표 함수는 function을 => 로 표기하는 것만이 전부가 아닙니다. 화살표 함수는 일반 함수와 구조가 다릅니다.

const book = function(){
  return 100;
};
const point = () => 100;

  • 일반 함수
    book의 스코프를 전개하면 prototype과 constructor가 있습니다
  • 화살표 함수
    1. point를 전개하면 prototype과 constructor가 없습니다.
    2. prototype에 메소드를 연결하여 확장할 수 없습니다.
    3. prototype이 없기에 가볍습니다.
    4. new 연산자로 인스턴스 생성이 불가능합니다.
    5. 즉, 단독으로 사용하라는 의미입니다.

arguments 사용 불가

화살표 함수에서는 arguments를 사용할 수 없습니다. 대신 rest parameter를 사용합니다.

const point = () => {
  try {
    const args = arguments;
  } catch(error) {
    console.log("arguments사용 불가");
  };
};
point(10, 20);
// arguments 사용 불가

  1. point(10, 20)형태로 호출하면 일반 함수에서는 arguments에 10, 20이 설정되지만, 화살표 함수에서는 ReferenceError가 발생합니다. 즉, arguments를 사용할 수 없습니다.
  2. scope에서 point함수 구조를 전개하면 arguments가 표시는 됩니다.

화살표 함수와 this

"use strict"
function book() {
  function getPoint() {
    console.log(this);
  };
  getPoint();
  // window.getPoint()
};
window.book();
// undefined
  • strict 모드에서 함수를 호출할 때 함수 앞에 오브젝트 작성은 필수입니다.
  1. strict 모드에서는 window.book()처럼 호출하는 함수 앞에 참조가 될 컨텍스트 오브젝트를 작성해야 합니다. 그렇지 않으면 함수 내 this값이 undefined입니다.
  2. 또한, getPoint()처럼 window를 앞에 작성하지 않으면 getPoint() 앞에서 this값이 undefined입니다.
  3. 이를 피하기 위해 window.getPoint()를 호출하면 window 오브젝트에 getPoint()가 없기에 에러가 발생합니다.
  4. strict 모드의 함수에서 this를 참조하기 위해서는 this를 별도 저장 후 사용해야 하는데 사용이 번거롭습니다.
"use strict"
var point = 100;
function sports() {
  const getPoint = () => { 
    console.log(this.point);
  };
  getPoint();
};
window.sports();
// 100
  • 이를 화살표 함수로 해결할 수 있습니다.
  1. 화살표 함수로 작성하면 getPoint를 호출할 수 있습니다.
  2. 또한, getPoint()화살표 함수 안에서this가 undefined가 아닌 글로벌 오브젝트(window)를 참조합니다.
  3. var point = 100;을 작성해놨기에 100이 출력됩니다.

코드 분석

"use strict"
const book = {
	point: 500,
	getPoint: function() {
		console.log(this.point);
	}
};
book.getPoint();
// 500

일반 함수인 book.getPoint()를 호출하면 함수 안에서this가 book 오브젝트를 참조합니다. 그렇기에 console에 500이 출력됩니다

var point = 100;
const sports = {
  getPoint: () => {
    console.log("this.point", this.point);
  }
};
sports.getPoint();
// this.point 100

  1. 화살표 함수인 sports.getPoint()를 호출하면 Scope Local에 this:undefined가 표시됩니다.
  2. 이는 화살표 함수는 함수에 this를 가지고 있지 않기 때문인데,
  3. 이때, this가 window 오브젝트를 참조합니다.
    • 항상 window를 참조하는 것은 아니고 상황에 따라 다르지만, 대부분의 경우 window 객체를 참조하게 됩니다.

this가 정적 스코프 참조

  • 화살표 함수에서 정적 스코프의 this를 사용
  • 정적(Lexical)스코프란?
    • 엔진이 해석할 때, 화살표 함수를 만나면
    • function 오브젝트를 생성하고
    • 화살표 함수가 속한 스코프를 생성한 오브젝트에 바인딩
  • 오브젝트에 바인딩된 스코프의 this를 화살표 함수에서 this로 사용합니다.
var title = "책";
const book = {
  show: () => console.log(this.title);
};
book.show();
  • show() 화살표 함수에서 this가 window 오브젝트를 참조합니다.
  • 이는 스코프를 통해 함수 외부 변수를 사용하는 것 처럼 book 오브젝트에 설정된 스코프의 this 바인딩 컴포넌트를 화살표 함수에서 this로 사용하기 때문입니다.
  • book 오브젝트는 글로벌 오브젝트에 설정되었으므로 this가 window 오브젝트를 참조하게 되는 것입니다.

화살표 함수와 인스턴스

인스턴스에서 화살표 함수의 작성 위치에 따라 this가 참조하는 오브젝트가 다릅니다.

var point = 200;
const Point = function() {
  this.point = 100;
};
Point.prototype.getPoint = () => {
  console.log(this.point);
};
new Point().getPoint();
// 200
  • prototype에 메소드로 작성
    • prototype에 화살표 함수를 연결하면 this는 글로벌 오브젝트를 참조합니다.
    • 때문에 this.point를 출력하면 내부에 선언된 point가 아닌 글로벌 오브젝트에 선언된 point인 200을 출력합니다.
const Point = function() {
  this.point = 100;
};
Point.prototype.getPoint = function() {
  const add = () => this.point + 20;
  console.log(add());
  [1, 2].forEach((value) => {
    console.log(this.point + value);
  })
};
new Point().getPoint();
// 120
// 101
// 102
  • prototype의 메소드 안에 작성
    ⇒ prototype에 일반 함수를 연결하고 함수 안에 화살표 함수를 작성하면
    • getPoint()가 일반 함수이므로 this가 생성한 인스턴스를 참조합니다.
    • 또한 화살표 함수에서도 this가 생성한 인스턴스를 참조합니다
    • 이는, 화살표 함수의 스코프인 getPoint()의 this를 사용하기 때문입니다.

정리

화살표 함수 특징

  • function 대신 => 를 사용, 함수 표현식 형태입니다.
  • prototype이 없기에 함수가 가볍고 constructor가 없기에 new 연산자로 인스턴스를 생성할 수 없습니다.
  • 화살표 함수에 this가 없다.
    • 화살표 함수로 Function 오브젝트를 생성할 때 정적으로 화살표 함수가 속한 스코프의 this를 화살표 함수에 바인딩합니다.
    • 바인딩 된 this 참조가 바뀌지 않으며 화살표 함수에서 this로 사용합니다.
    • 일반 함수는 call()등을 이용해 바꿀 수 있습니다.
  • 메소드보다 함수로 사용하는 것이 효율성이 높습니다.

좋은 웹페이지 즐겨찾기