# 화살표함수

🔗 🔗 🔗

저는 gitlab FE 인터뷰 자료의 javascript 를 다 읽어보고 공부를 하고 있습니다. 몇몇 스터디 원분들께서는 그래서 제가 정리한 공부의 문맥이 이해가 안되실 수 있습니다. 문맥의 이해가 안되실땐, 궁금하면 저한테 질문을 주시거나. 아니면 넘어가고 나중에 다시 이해하셔도 됩니다.

# 개요

  • this, arguments, super, new.target 을 바인딩 하지 않는다. TODO about
  • 익명함수 이기 때문에, 메서드가 아닌 함수에 사용하는 것이 적절하다.
  • 익명 함수이기 때문에 생성자로 사용할 수 없다.

# 화살표 함수는 단순히 짧게 쓰는 용도로만 사용되지 않는다.

  • arr.forEach(func), setTimeout(func) 같은 func 를 생성하고 여기에 전달하는 것이 자연스럽다.
  • 그런데 외부에다 생성을 하여 전달하게 되면 함수의 컨텍스트를 잃어버릴 수 있는데, 이때 화살표 함수를 사용한다.

new 생성자로 생성한 Person 객체의 this 는 자신의 인스턴스로 정의된다.
그러나 setInterval 내의 인수의 콜백함수의 this 는 비엄격모드에서 전역을 가리킨다.

function Person() {
    this.age = 0;
    setInterval(function growUp () {
        this.age++
    }, 1000)
}
var p = new Person();
1
2
3
4
5
6
7

변수로 this 를 정의해 콜백 함수에서 사용한다.

function  Person() {
    var that = this;
    that.age = 0;
    
    setInterval(function growUp() {
        that.age++;
    }, 1000);
}
1
2
3
4
5
6
7
8

# 문법

  1. 객체 리터럴 식을 반환
    params => ({foo: bar})
  2. 나머지 매개변수 지원
    (param1, param2, ...rest) => { statements }
    
    1
  3. 기본 매개변수 지원
    (param1 = defaultValue1, param2, ... , paramN = defaultValueN) => { statements }
    
    1
  4. 매개변수 목록 내 구조분해 지원
    var f = ([a, b] = [1, 2], {x: c} = { x: a + b}) => a + b + c;
    
    1

# 동적 화살표 함수

let age = prompt('나이를 알려주세요.', 18);
let welcome = (age < 18) ? 
    () => alert('안녕') :
    () => alert('안녕하세요!');

welcome();
1
2
3
4
5
6

# 파싱 순서

일반 함수와 비교했을 때 연산자 우선순위가 다르게 반응한다.

let callback;
callback = callback || function () {}; 
callback = callback || () => {};    // SyntaxError: invalid arrow-function arguments
callback = callback || (() => {});
1
2
3
4

TODO 3번줄을 디버깅해보자

# 화살표 함수에는 'this' 가 없다.

화살표 함수 본문에서 this 에 접근하면, 외부에서 값을 가져온다.

화살표 함수의 this 는 showList() 의 this 와 같다.

let group = {
    title: '1모둠',
    students: ["보라", "호진", "지민"],
    showList() {
        this.students.forEach(
            student => alert(this.title + ': ' + student)
        );   
    }
};
group.showList();
1
2
3
4
5
6
7
8
9
10

forEach 에 전달되는 this 는 undefined 가 된다.
콜백 함수를 호출하는 함수의 내부를 알아야 this 를 알수 있다.

let group = {
    title: '1모둠',
    students: ["보라", "호진", "지민"],
    showList() {
        this.students.forEach(function(student) {
            // TypeError: Cannot read property 'title' of undefined
            alert(this.title+': '+student);
        })
    }
}
group.showList();
1
2
3
4
5
6
7
8
9
10
11

콜백 함수를 호출하는 함수의 두번째 인자에 this 를 명시해 줄 수 있다.

let group = {
    title: '1모둠',
    students: ["보라", "호진", "지민"],
    showList() {
        this.students.forEach(function(student) {
            // TypeError: Cannot read property 'title' of undefined
            alert(this.title + ': '+student);
        }, group)
    }
}
group.showList();
1
2
3
4
5
6
7
8
9
10
11

# 화살표 함수는 new 와 함께 실행할 수 없다.

  • this 가 없기 때문에 화살표 함수는 생성자 함수로 사용할 수 없다.
var Foo = () => {};
var foo = new Foo();    // TypeError: Foo is not a constructor
1
2

# 화살표 함수엔 'arguments' 가 없다.

function defer (f, ms) {
    return function() {
        setTimeout(() => f.apply(this, arguments), ms);
    }
}
function sayHi(who) {
    alert('안녕, ' + who);
}
let sayHiDeferred = defer(sayHi, 2000);
sayHiDeferred('철수');
1
2
3
4
5
6
7
8
9
10

this 값과, arguments 정보를 함께 실어 호출을 포워딩해 주는 데코레이터를 만들때 유용하다.
데코레이터 defer(f, ms) 는 함수를 인자로 받고 이 함수를 래퍼로 감싸 반환한다. 함수 f 는 ms 밀리초 이후에 호출된다.

화살표 함수를 동일한 기능을 하려면, setTimeout 함수의 콜백함수에서 사용할 변수를 만들어 줘야한다.

function defer(f, ms) {
    return function(...args) {
        let ctx = this;
        setTimeout(function() {
            return f.apply(ctx, args)
        })
    }
}
1
2
3
4
5
6
7
8

화살표 함수의 arguments 객체 대신에 나머지 매개변수를 사용한다.

function foo(n) {
    var f = (...args) => args[0] + n;
    return f(2);
}
f(1);
1
2
3
4
5

# super 가 없다.

TODO 클래스 상속

화살표 함수와 this - 강사님 예제 고급 특징

# 엄격 모드와의 관계

this가 렉시컬임을 감안하면 this 에 관한 엄격모드 규칙은 무시된다.

var f = () => {'use strict'; return this;}
f() === window;
1
2

# 메서드로 사용되는 화살표 함수

'use strict'

var obj = {
    i: 10,
    b: () => console.log(this.i, this),
    c: function() {
        console.log(this.i, this)
    }
}
1
2
3
4
5
6
7
8
9

일반메서드 c 는 obj 가 this

obj.c(); // 10, Object { ... }
1

화살표 메서드 b 는 전역 실행문맥에서 실행되고 있으므로 this 는 Window 가 된다.

obj.b(); // undefined, Window
1

접근자 프로퍼티의 함수로 사용되는 화살표 함수

'use strict';

var obj = {
    a: 10
};
Object.defineProperty(obj, 'b', {
    get: () => {
        console.log(this.a, typeof this.a, this); // undefined 'undefined' Window {...} (or the global object)
        return this.a + 10; // returns 'undefined'
    }
})
1
2
3
4
5
6
7
8
9
10
11

# prototype 속성이 없다.

var Foo = () => {};
console.log(Foo.prototype);     // undefined
1
2

# yield 키워드를 사용할 수 없다.

화살표 함수는 생성기(generator) 로서 사용될 수 없다.

화살표 함수의 중첩 함수 내에서는 사용가능하다.