본문 바로가기
Front-End/Javascript

화살표 함수 (arrow function)

by kimik 2018. 5. 25.
// 매개변수 지정 방법
    () => { ... } // 매개변수가 없을 경우
     x => { ... } // 매개변수가 한 개인 경우, 소괄호를 생략할 수 있다.
(x, y) => { ... } // 매개변수가 여러 개인 경우, 소괄호를 생략할 수 없다.

// 함수 몸체 지정 방법
x => { return x * x }  // single line block
x => x * x             // 함수 몸체가 한줄의 구문이라면 중괄호를 생략할 수 있으며 암묵적으로 return된다. 
//위 표현과 동일하다.

() => { return { a: 1 }; }
() => ({ a: 1 })  // 위 표현과 동일하다. 객체 반환시 소괄호를 사용한다.

() => {           // multi line block.
  const x = 10;
  return x * x;
};
1.화살표 함수 호출
// ES5는 return을 써야만 return이 되지만,
var pow = function (x) { return x * x; };
console.log(pow(10)); // 100

// ES6는 1줄 표현식의 경우 무조건 return으로 처리된다.
const pow = x => x * x;
console.log(pow(10)); // 100

2.this의 차이

//es5
function Prefixer(prefix) {
  this.prefix = prefix;
}

Prefixer.prototype.prefixArray = function (arr) {
  // (A)
  return arr.map(function (x) {
    console.log(this) //es5의 경우 this가 Window 객체를 바라본다.
  });
};

var pre = new Prefixer('Hi');
console.log(pre.prefixArray(['Lee', 'Kim']));

//es6 
function Prefixer(prefix) {
  this.prefix = prefix;
}

Prefixer.prototype.prefixArray = function (arr) {
  return arr.map(x => { 
    console.log(this); //es6의 화살표함수에서 this는 Prefixer객체를 바라본다.
   });
};

const pre = new Prefixer('Hi');
console.log(pre.prefixArray(['Lee', 'Kim']));
위의 es6를 babel로 컴파일하여 es5로 보게되면,
'use strict';

function Prefixer(prefix) {
  this.prefix = prefix;
}

Prefixer.prototype.prefixArray = function (arr) {
  var _this = this; //_this라는 변수를 만들어 Prefixer객체를 담는다.

  return arr.map(function (x) {
    console.log(_this); // 위에서 만든 _this변수에 Prefixer객체가 es6처럼 Prefixer객체를 바라본다.
  });
};

var pre = new Prefixer('Hi');
console.log(pre.prefixArray(['Lee', 'Kim']));

이런식으로 처리된다. es6에서 화살표함수안에 this를 Lexical this라고 한다. 


3.화살표함수를 사용하면 안되는경우.


3-1.메소드

// 나쁜예
const person = {
  name: 'Lee',
  sayHi: () => console.log(`Hi ${this.name}`)  /*여기서의 this는 person바라봐야하지만, undefined가 찍힘.*/
};

person.sayHi(); // Hi undefined

// 좋은 예
const person = {
  name: 'Lee',
  sayHi() { // === sayHi: function() {
    console.log(`Hi ${this.name}`); /*es6 축약 메소드표현으로 화살표함수는 아니지만 
function을 생략하여 sayHi: function() { 와 같은 효과를 지니게 됨. 고로 this = person 을 바라봄.*/
  }
};

person.sayHi(); // Hi Lee

3-2.prototype

// 나쁜 예
const person = {
  name: 'Lee',
};

Object.prototype.sayHi = () => console.log(`Hi ${this.name}`); // this = undefined

person.sayHi(); // Hi undefined

// 좋은 예
const person = {
  name: 'Lee',
};

Object.prototype.sayHi = function() {
  console.log(`Hi ${this.name}`); // this = person 
};

person.sayHi(); // Hi Lee

3-3.addEventListener 함수의 콜백 함수

// 나쁜예
var button = document.getElementById('myButton');

button.addEventListener('click', () => {
  console.log(this === window); // => true,즉 this = window
  this.innerHTML = 'Clicked button';
});

// 좋은예 
var button = document.getElementById('myButton');

button.addEventListener('click', function() {
  console.log(this === button); // => true 즉, this = button 
  this.innerHTML = 'Clicked button';
});

3-4.생성자 함수

const Foo = () => {};

// 화살표 함수는 prototype 프로퍼티가 없다
console.log(Foo.hasOwnProperty('prototype')); // false

const foo = new Foo(); // TypeError: Foo is not a constructor

 * bable로 생성자함수를 변화시키면,

var Foo = function Foo() {};

console.log(Foo.hasOwnProperty('prototype')); // true
var foo = new Foo(); 

이와같이 출력되어 오류가 없다.


*요약


1.화살표 함수가 한줄일땐 return 이 생략됨.


2.화살표 함수의 this는 Lexical this 이므로 항상 자신을 보함하고있는 상위 컨텍스트의 this를 계승받음.


3. 화살표 함수를 사용해선 안되는것을 항상 숙지( 메소드, 프로토타입, 이벤트 리스너)


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


댓글