화살표 함수

nubim·2025년 2월 7일
// 객체 리터럴 반환 시 () 감싸주어야 한다
const arrow = (id, content) => ({ id, content })
console.log(1, 'js') // {id: 1, content: js}
// arrow function with IIFE
const person = (name => ({
	sayHi() { return `Hi? My name is ${name}`; }
})){'Lee'};

console.log(person.sayHi()); // Hi? My name is Lee

일반 함수 vs 화살표 함수

  • 일반 함수와 화살표 함수의 가장 큰 특징은 this
  • 화살표 함수는 인스턴스를 생성할 수 없다 (non-constructor)
    const Foo = () => {};
    new Foo() // TypeError: Foo is not a constructor
  • 화살표 함수는 중복된 매게 변수명 선언 불가
    // 일반 함수는 매게변수명 중복 가능, 하지만 가독성때문에 비추
    function normal(a, a) { return a + a; }
    console.log(normal(1, 2)); // 4
    
    // strict mode에서는 일반 함수도 불가
    'use strict'
    function normal(a, a) { return a + a; }
    // SyntaxError: Duplicate parameter name not allowed in this context
    
    // 화살표 함수에서는 매게변수명 중복 불가
    const arrow = (a, a) => a + a;
    // SyntaxError... 
  • 화살표 함수는 함수 자체의 this, arguments, super, new target 바인딩을 갖지 않는다
    • 화살표 함수 내부에서 this, arguments, super, new.target을 참조하면 스코프 체인을 통해 상위 스코프의 this, arguments, super, new.target을 참조한다 만약 활살표 함수가 중첩된 2중 화살표 함수라면 상위 함수 중에서 화살표 함수가 아닌 함수의 this, arguments, super, ner.target를 참조

화살표 함수의 this

  • 일반 함수의 this와 다르게 동작한다
  • 이는 “콜백 함수 내부의 this가 외부 함수의 this와 달라 발생하는 문제”를 해결하기 위해 의도된 설계
  • 화살표 함수의 this는 함수가 선언된 위치의 상위 스코프에 바인딩되며, 호출 방법에 따라 this가 달라지지 않는다.
**// Good**
#1
const person = {
	name: 'Lee'
	// ES6 메서드 축약 표현
	sayHi() {
		console.log(`Hi ${this.name}`)
	}
}

person.sayHi(); // Hi Lee

#2
function Person(name) {
	this.name = name;
}

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

const person = new Person('Lee');
person.sayHi() // Hi Lee

**// Bad**
function Person(name) {
	this.name = name;
}

Person.prototype.sayHi = () => console.log(`Hi ${this.name}`);
const person = new Person('Lee'); // Hi 화살표 함수의 this.name은 window.name 즉 빈문자열
  • 다음 클래스에서의 화살표 함수의 상위 스코프는 constructor다, 즉 프로토타입의 메서드가 아닌 인스턴스의 메서드가 된다, 결국 생선한 인스턴스를 가리키지만 ES6 메서드 축약이나 일반함수를 사용하는 것을 권장
class Person {
    constructor() {
        this.name = 'Lee' ;
        this.sayHi = () => console.log(`Hi ${this.name}`);
    }
}

const person = new Person
person.sayHi() // Hi Lee

**// Good**
class Person {
  name = 'Lee' ;
  sayHi() { console.log(`Hi ${this.name}`); };
}

const person = new Person
person.sayHi() // Hi Lee

화살표 함수의 super

  • this와 마찬가지로 상위 스코프의 super를 참조
// Derived의 sayHi는 ES6 메서드는 아니지만 함수 자체의 super 바인딩을 갖지 않으므로 super를 참조해도 에러가 발생하지 않음
// 상위 스코프인 constructor의 super 바인딩을 참조

class Base {
  constructor(name) {
    this.name = name;
  }

  sayHi() {
    return `Hi! ${this.name}`;
  }
}

class Derived extends Base {
  // 화살표 함수의 super는 상위 스코프인 constructor의 super를 가진다.
  sayHi = () => `${super.sayHi()} how are you doing?`;
}

const derived = new Derived('Lee');
console.log(derived.sayHi());  // Hi! Lee how are you doing?

화살표 함수의 arguments와 Rest 파라미터

  • 화살표 함수 내부에서 arguments를 참조하면 this와 마찬가지로 상위 스코프의 arguments를 참조
  • 상위 스코프껄 참조할 수 있지만 자신에게 전달된 인수 목록을 확인할 수 없기에 도움이 되지 않는다, 때문에 그런 특징이 있다 정도로 알아두고 화살표 함수로 가변 인자 함수를 구현해야 할 때는 반드시 Rest 파라미터 권장
(function () {
  // 화살표 함수 foo의 arguments는 상위 스코프인 즉시 실행 함수의 arguments를 가리킨다.
  const foo = () => console.log(arguments); // [Arguments] { '0': 1, '1': 2 }
  foo(3, 4);
})(1, 2);

// 화살표 함수 foo의 arguments는 상위 스코프인 전역의 arguments를 가리킨다.
// 하지만 전역에는 arguments 객체가 존재하지 않는다. arguments 객체는 함수 내부에서만 유효하다.
const foo = () => console.log(arguments);
foo(1, 2); // ReferenceError: arguments is not defined
  • Rest 파라미터
    • … 을 붙여서 함수로 전달된 인수들의 목록을 배열로 반환
    • Rest 파라미터는 할당된 인수를 제외한 나머지 인수들이기에 반드시 마지막 파라미터야 한다
    • 1개만 선언 가능
**// 반드시 마지막 파라미터!!!
#1**
function foo(param, ...rest) {
  console.log(param); // 1
  console.log(rest);  // [2, 3, 4, 5]
}

foo(1, 2, 3, 4, 5);

function bar(param1, param2, ...rest) {
  console.log(param1); // 1
  console.log(param2); // 2
  console.log(rest);   // [3, 4, 5]
}

bar(1, 2, 3, 4, 5);

#2
function sum(...args) {
  // Rest 파라미터 args에는 배열 [1, 2, 3, 4, 5]가 할당된다.
  return args.reduce((pre, cur) => pre + cur, 0);
}

console.log(sum(1, 2, 3, 4, 5)); // 15

// Bad
// 1개여야 하고 마지막에 있어야 하고 
#1
function foo(...rest, param1, param2) { }

foo(1, 2, 3, 4, 5);
// SyntaxError: Rest parameter must be last formal parameter

#2
function foo(...rest1, ...rest2) { }

foo(1, 2, 3, 4, 5);
// SyntaxError: Rest parameter must be last formal parameter

0개의 댓글