20210709 JavaSciprt DeepDive 08 : ES6 메서드(축약표현), 화살표 함수, Rest 파라미터, 매개변수 기본값
JavaScript Deep Dive 08
📄 용어 및 중요사항 정리
ES6 함수의 추가 기능
- 자바스크립트에서 ES6 이전 함수는 다양한 방식으로 호출이 가능함 -> 함수의 구분이 없음, 대부분이 프로토타입 객체를 생성함 -> 실수 유발, 성능 저하
    
- 일반 함수 호출
 - 생성자 함수 호출
 - 메서드로서 호출
 - callble(호출할 수 있는 함수 객체) 이면서 contructor(인스턴스를 생성할 수 있는 함수 객체) 임
 
 
| 함수 구분 | constructor | prototype | super | arguments | 
|---|---|---|---|---|
| 일반함수  (함수 선언문, 표현식)  | 
      O | O | X | O | 
| 메서드 | X | X | O | O | 
| 화살표 함수 | X | X | X | X | 
ES6 메서드 (메서드 축약 표현)
메서드:- 과거 : 객체에 바인딩된 함수를 일컫는 의미
 - ES6 : 
메서드 축약 표현으로 정의된 함수만 의미- non-consturctor로 인스턴스 생성 X -> 생성자 함수로서 호출 X
 - prototype 프로퍼티 X, 프로토타입 생성 X
 
 - 표준 빌트인 객체가 제공하는 프로토타입 메서드, 정적 메서드는 non-contructor 임 (메서드니까)
 - ES6 메서드는 자신을 바인딩한 객체를 가리키는 내부 슬롯 [[HomeObject]]를 갖음 -> super 키워드 사용 가능
        
- 객체 리터럴 방식의 객체의 __proto__ 프로퍼티에 부모를 할당하여 상속 구현이 가능함
 
 - 메서드 정의시 프로퍼티에 익명 함수 표현식을 할당하는 방식은 사용하지 말자
 
const obj = {
  x: 1,
  foo() {
    return this.x;
  }, // ES6 메서드
  bar: function () {
    return this.x;
  }, // 일반 함수
};
console.log(obj.foo()); // 1 (ES6 메서드)
console.log(obj.bar()); // 1 (일반 함수)
new obj.foo(); // Type Error : not a constructor (ES6 메서드)
new obj.bar(); // bar{} (일반 함수)
obj.foo.hasOwnProperty("prototype"); // false (ES6 메서드)
obj.bar.hasOwnProperty("prototype"); // true (일반 함수)
화살표 함수
화살표 함수:- 함수 선언문으로 정의할 수 없고 함수 표현식으로 정의함 (호출 방식은 기존 함수와 동일)
 - 매개변수 :
        
- 매개 변수가 여러 개인 경우 소괄호 ()안에 매개변수 선언
 - 1개인 경우 소괄호 생략 가능, 0개인 경우 소괄호 생략 불가
 - 중복된 매개변수 이름 선언 X, Duplicate prameter name X (일반 함수는 가능함)
 
 - 함수 몸체 :
        
- 표현식인 문 하나로 된 경우만 중괄호 생략 가능 (해당 표현식인 문은 return 값으로 인식)
            
- 여러개의 문으로 구성되면 중괄호 생략 불가
 
 - 객체 리터럴 반환시 ()소괄호로 묶어주어야 함
            
- 객체 리터럴의 중괄호 보다, 함수 몸체를 의미하는 중괄호가 우선되어 인식
 
 
 - 표현식인 문 하나로 된 경우만 중괄호 생략 가능 (해당 표현식인 문은 return 값으로 인식)
            
 - 즉시 실행 함수 사용 가능
 - 화살표 함수는 일급객체임 -> 고차함수(HOF)에 인수로 전달 가능
        
- 콜백함수 정의시 유용
 
 - 인스턴스 생성 불가한 non-constructor 임 -> 생성자 함수로서 호출 X, 프로토타입 생성 X
 - 함수 자체 this, arguments, super, new.target 바인딩 X -> 상위 스코프 기준으로 바인딩 O
 - 화살표 함수로 기존의 메서드를 만들지 말자, 메서드는 항상 ES6 메서드 축약만 사용하자
 
화살표 함수의 this콜백함수 내부의 this 문제- 콜백함수가 함수 표현식으로 작성된 경우, 콜백함수는 일반 함수로 호출 됨
        
- 일반 함수로 호출되면 this는 전역객체를 가리킴
 - strict mode + 일반함수 호출 -> this는 undefined를 가리킴
 
 - 콜백함수 외부 this와 콜백함수 내부의 this가 차이가 생김
 콜백 함수 내/외부 this를 일치 시키는 방법- 방법01: 외부에서 this를 변수에 할당시켜 받아서, 내부에서 변수을 참조하여 사용
 - 방법02: 두번째 인수를 콜백함수 내부의 this로 사용할 객체를 전달하는 기능이 있는 함수를 사용
            
- ex) Array.prototype.map(callback, this)
 
 - 방법03: Function.prototype.bind 메서드 활용하여 콜백함수에 bind를 붙여 외부 this를 바인딩
            
- bind() : 내부 this에 바인딩 될 값을 지정함 (.bind(this) -> 외부 this를 바인딩)
 
 - 방법04: 화살표 함수를 사용하기
            
- 화살표 함수는 자체 this 바인딩이 없어 this 사용시 상위 스코프의 this를 그대로 참조하는 특성을 가졌음
 lexical this: 화살표 함수의 this의 기능을 가진 this를 말함- 렉시컬 스코프처럼, 화살표 함수가 정의된 위치에 의해 this가 결정되는 것
 - 화살표 함수가 중첩되어 있는 경우 -> 화살표 함수가 아닌 가장 가까운 함수의 this를 참조
 
- 화살표 함수의 경우 this 바인딩이 없기 때문에 call, apply, bind 메서드를 사용해도 this 지정이 불가함
 
 
- 콜백함수가 함수 표현식으로 작성된 경우, 콜백함수는 일반 함수로 호출 됨
        
 
// 화살표 함수의 this 바인딩
// call을 통해서 외부 함수의 this가 정해짐 -> 화살표 함수 this 검색을 통한 this 참조가 일어남
(function () {
  const foo = () => console.log(this);
  foo();
}.call({ a: 1 })); // { a: 1 }
// 화살표 함수 중첩인 경우 this 검색
(function () {
  const bar = () = () => console.log(this);
  bar();
}.call({ a: 1 })); // { a: 1 }
// 화살표 함수에서 call, apply, bind 메서드 무시 (this가 없으므로)
window.x = 1
const normal = function() {return this.x}
const arrow = () => this.x
console.log(normal.call({x: 10})) // 10
console.log(arrow.call({x: 10})) // 1
프로토타입 객체의 프로퍼티에 함수를 넣는 경우- 화살표 함수로 할당하는 경우 화살표 함수의 this는 window를 가리킴
 - 함수 표현식을 할당하는 경우 this는 호출된 인스턴스를 가리킴
 - ES6 메서드를 사용하는 경우 프로토타입 객체에 새로운 객체를 할당하는 방식으로 ES6메서드를 사용하고, constructor 프로퍼티를 만들어서 생성자 함수간의 연결을 해줘야 함
 
클래스 필드에 화살표 함수 할당- 클래스 필드에 this를 포함하는 화살표 함수를 할당하는 경우 -> 예외적으로 this는 인스턴스를 가리킴
        
- 이 상황에서 화살표 함수의 상위 스코프는 클래스 외부임
 
 
- 클래스 필드에 this를 포함하는 화살표 함수를 할당하는 경우 -> 예외적으로 this는 인스턴스를 가리킴
        
 클래스의 constructor 메서드에 화살표 함수 할당- 클래스 필드와 마찬가지로 this가 인스턴스를 가리킴
 
- 
    
화살표 함수의 super- 화살표 함수는 함수 자체 super 바인딩이 없어 화살표 함수 자신 자체의 super를 사용할 수 없음
 - 화살표 함수에서 super 참조시 this와 마찬가지로 상위 스코프 contructor의 super참조
 - super은 [[HomeObject]]를 갖는 ES6 메서드 내에서만 사용할수 있는 키워드임
 - 클래스 필드에 super를 참조하는 화살표 함수를 할당하면, constructor 내부의 super를 바인딩을 참조함
        
- 클래스 필드를 사용하면, constructor를 생략해도 암묵적으로 constructor가 생성되므로
 
 
 - 
    
화살표 함수의 arguments- 화살표 함수는 arguments 바인딩이 없어서 화살표 함수 자체의 arguments 객체를 사용할 수 없음
 - 상위 스코프의 arguments를 참조함
        
- arguments가 작용되더라도 상위 스코프 arguments 객체인 것임
 
 
 
Rest 파라미터
Rest 파라미터: 함수에 전달된 인수들의 목록을 배열로 전달 받음...매개변수의 형태로 매개변수를 작성함- Rest 파라미터는 반드시 마지막 파라미터이어야 함
 - Rest 파라미터는 단 하나만 선언 가능함
 - 일반 매개 변수와 rest 파라미터를 함께 사용할 수 있음
        
- 인수는 매개변수, rest 파라미터 순차적으로 할당 됨
 - 매개변수는 매개변수 대로 인수가 들어가고, rest 파라미터 순서 부터는 rest 파라미터에 할당됨 (rest 파라미터에는 매개변수의 인수는 제외 됨)
 
 - Rest 파라미터는 함수객체의 length 프로퍼티에 포함되지 않음
        
- length 프로퍼티 : 함수정의시 선언한 매개변수의 개수
 
 
Rest 파라미터 vs arguments 객체
| 비교 | Rest 파라미터 | arguments 객체 | 
|---|---|---|
| 개념 | 인수 정보 O | 인수 정보 O | 
| 표현 | …매개변수 | 자동 생성됨 | 
| 반환 | 배열 객체 | 유사 배열 객체 | 
| 배열 메서드 | 직접 사용 가능 | call, apply로 간접적으로  사용해서 변환 필요  | 
    
| 함수 내부  지역변수 사용  | 
      O (매개변수) | O(arguments) | 
| (ES6)단축 메서드 | O | O | 
| 화살표 함수 | O | X | 
| 기본값 지정 기능 | X | O (영향 안받기 때문) | 
매개변수 기본값- JS 엔진은 매개변수와 인수의 개수를 체크 X -> error 발생 X
 - 인수가 전달되지 않은 매개변수 : undefined
        
- 기존 논리 연산자를 통한 인수 체크 및 기본값 설정 방식 (or 연산자)
 
 - ES6의 인수체크 및 초기화
        
- 매개변수에 할당 연산자를 통해서 값을 할당하는 표현으로 사용함
 - 인수전달 안한 경우, undefined 전달한 경우에만 기본값이 작용됨
 
 - rest 파라미터는 ES6 방식 기본값 설정 불가
 - arguments객체 영향 받지 않음 (기본값 사용 가능)
 
function sum1(x, y) {
  x = x || 0;
  y = y || 0;
  return x + y;
}
console.log(sum1(1, 2)); // 3
console.log(sum1(1)); // 1
function sum2(x = 0, y = 0) {
  return x + y;
}
console.log(sum2(1, 2)); // 3
console.log(sum2(1)); // 1