본문 바로가기
[Study] Deep Dive 스터디

[JS] ES6 함수의 추가 기능

by 지공A 2024. 1. 16.

26장 : ES6 함수의 추가 기능

1. 함수의 구분

  • ES6에서는 함수를 사용 목적에 따라 세 가지 종류로 구분한다.
ES6 함수의 구분 constructor prototype super arguments
일반 함수 O O X O
메서드 X X O O
화살표 함수 X X X X

2. 메서드

  • ES6 사양에서 메서드는 메서드 축약 표현(function 키워드 생략)으로 정의된 함수만을 의미한다.
const obj = {
    x:1,
    // foo : 메서드
    foo() {return this.x},
    // bar 에 바인딩된 함수는 메서드가 아닌 일반 함수
    bar: function() {return this.x;}
}

new obj.foo();  // TypeError : obj.foo is not a cunstructor
new obj.bar(); // bar {}
  • ES6 사양에서 정의한 메서드는 인스턴스를 생성할 수 없는 non-constructor다.
  • 따라서 ES6 메서드는 생성자 함수로서 호출할 수 없다.
  • 또한 인스턴스를 생성할 수 없으므로 prototype 프로퍼티가 없고, 프로토타입도 생성하지 않는다.
  • ES6 메서드가 아닌 함수는 super 키워드를 사용할 수 없다.
super?
클래스의 상속 관계에서 부모 클래스를 가리키는 특별한 키워드
주로 자식 클래스에서 부모 클래스의 메서드를 호출하거나 부모 클래스의 생성자를 호출할 때 사용

3. 화살표 함수

 1. 일반 함수 정의

  • 함수 정의 : 함수 선언문으로 정의할 수 없고 함수 표현식으로 정의해야 한다.
  • 함수 몸체 정의 : 함수 몸체가 하나의 문으로 구성된다면 중괄호 {} 생략 가능 
const multiply = (x, y) => x * y;
  • 매개변수 선언 
// 매개변수가 여러 개
const arrow = (x, y) => { ... };

// 매개변수가 한 개
const arrow2 = x => { ... };

// 매개변수가 없는 경우
const arrow3 = () => { ... };

 

 

2. 화살표 함수와 일반 함수의 차이

  • 화살표 함수는 인스턴스를 생성할 수 없는 non-constructor
const Foo = () => {};
// 화살표 함수는 생성자 함수로서 호출 불가
new Foo(); // TypeError: Foo is not a constructor
  • 중복된 매개변수 이름을 선언할 수 없다.
    • 일반 함수는 중복된 매개변수 이름을 선언할 수 있지만, strict mode에서는 에러 발생
  • 화살표 함수는 함수 자체의 this, arguments, super, new.target 바인딩을 갖지 않으며 상위 스코프를 참조한다.

 

3. this

  • 화살표 함수는 함수 자체의 this 바인딩을 갖지 않는다.
  • 따라서 화살표 함수 내부에서 this를 참조하면 상위 스코프의 this를 그대로 참조하며 이를 lexical this라고 한다.
  • 이는 화살표 함수의 this가 함수가 정의된 위치에 의해 결정된다는 것을 의미한다.
class Prefixer {
  constructor(prefix) {
    this.prefix = prefix;
  }

  // 일반 함수 사용
  add(arr) {
    return arr.map(function (item) {
      return this.prefix + item;
      // TypeError: Cannot read property 'prefix' of undefined
    });
  }

  // 화살표 함수 사용
  addArrow(arr) {
    return arr.map((item) => this.prefix + item);
  }
}

const prefixer = new Prefixer("-webkit-");
console.log(prefixer.add(["transition", "user-select"]));
console.log(prefixer.addArrow(["transition", "user-select"]));
// ['-webkit-transition', '-webkit-user-select']
  • add 메서드 :  arr.map 메서드가 콜백 함수를 일반 함수로서 호출하기 때문에 this는 undefined를 가리킨다.
  • addArrow 메서드 : 화살표 함수 내부에서 this는 상위 스코프인 Prefixer를 가리킨다.

 

4. super

  • 화살표 함수는 함수 자체의 super 바인딩을 갖지 않는다.
  • 따라서 화살표 함수 내부에서 super를 참조하면 상위 스코프의 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?
  • Derived 클래스의 constructor는 생략되었지만 암묵적으로 constructor가 생성된다.

5. arguments

  • 화살표 함수 내부에서 arguments를 참조하면 this와 마찬가지로 상위 스코프의 arguments를 참조한다.
  • 화살표 함수에서는 상위 스코프의 arguments 객체를 참조할 수는 있지만 화살표 함수 자신에게 전달된 인수 목록을 확인할 수 없다.
(function () {
  // 화살표 함수 foo의 arguments는 상위 스코프인 즉시 실행 함수의 arguments를 가리킨다
  const foo = () => console.log(arguments); // [Arguments] { '0' : 1, '1': 2 }
  foo(3, 4);
})(1, 2);

const foo = () => console.log(arguments);
foo(1, 2); // ReferenceError: arguments is not defined

 


4. Rest 파라미터

1. 기본 문법

  • Rest 파라미터는 함수에 전달된 인수들의 목록을 배열로 전달받는다.
function foo(...rest) {
  // 매개변수 rest는 인수들의 목록을 배열로 전달받는 Rest 파라미터다
  console.log(rest); // [ 1, 2, 3, 4, 5 ]
}

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

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

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

 

 

2. Rest 파라미터와 arguments 객체

  • ES6에서는 Rest 파라미터를 사용하여 가변 인자 함수의 인수 목록을 배열로 직접 전달받을 수 있다.
  • 화살표 함수는 함수 자체의 arguments 객체를 갖지 않기 때문에 화살표 함수로 가변 인자 함수를 구현해야 할 때는 반드시 Rest 파라미터를 사용해야 한다.

5. 매개변수 기본값

  • 인수가 전달되지 않은 매개변수의 값은 undefined다.
  • ES6에서 도입된 매개변수 기본값을 사용할 수 있다.
  • 매개변수 기본값은 매개변수에 인수를 전달하지 않은 경우와 undefined를 전달한 경우에만 유효하다.
  • 또한, Rest 파라미터에는 기본값을 지정할 수 없다.
function sum(x, y) {
  return x + y;
}

console.log(sum(1)); // NaN

function sumDefault(x = 0, y = 0) {
  return x + y;
}

console.log(sumDefault(1)); // 1

 


Deep Dive Study week - 01

'[Study] Deep Dive 스터디' 카테고리의 다른 글

[JS] 이터러블  (0) 2024.01.23
[JS] 프로미스  (0) 2024.01.22
[JS] 비동기 프로그래밍  (0) 2024.01.20
[JS] 클로저  (0) 2024.01.14
[JS] this  (1) 2024.01.13