본문 바로가기
Front-End/JavaScript

26장 ES6 함수 (모던 자바스크립트 Deep Dive)

by kk님 2023. 5. 4.

모던 자바스크립트 Deep Dive 글 목록(스터디)
https://hello-kk.tistory.com/780


일반함수: 생성자 함수(즉 prototype 존재)

 

메서드: 축약 표현으로 정의된 함수=> non-constructor, function 키워드 생략하여 정의, super키워드 사용 가능. 

일반 함수와 다르게 구분한 이유

: 생성자 기능까지 더해지는 경우 prototype까지 생성되기 때문. 따라서 ES6에서는 메서드를 non-constructor로 지정함.


화살표 함수
: non-constructor이며, this, super, arguments도 바인딩되지 않아서 상위 스코프를 참조

 

 

객체에서, 메서드

메서드: ES6에서는 축약 표현으로 정의된 함수만을 의미함

const obj = {
    increase(){
        // ES6 메서드로 정의하는 것이 바람직
    }
}

메서드 아님

const obj = {
    increase: function(){
        
    }
}

const obj = {
    increase: ()=>{
        
    }
}

따라서, 동적으로 프로퍼티를 할당한다고 하면 this를 참조하는 범위가 달라질 수 있기 때문에,

객체 리터럴을 바인딩해야 함

 

화살표 함수는 this바인딩을 갖지 않는다

따라서, 상위 스코프의 this를 참조

 

화살표 함수는 super 바인딩을 갖지 않는다

따라서, 상위 스코프의 super를 참조

 

화살표 함수는 arguments 바인딩을 갖지 않는다

따라서, 상위 스코프의 arguments 를 참조(arguments 객체는 유사 배열 객체 => {length: 2, '0': 1, '1':2})

화살표 함수로 가변 인자 함수를 구할 땐, Rest 파라미터 사용!

 

메서드를 할당하는게 헷갈린다

=> 메서드를 할당하는 부분에선 그 함수를 직접 가져온다고 생각하자. 그러면 this가 어디 소속인지 바로 보임

 

arrow function은 코드를 평가할 때, this가 결정됨


일반 함수로 호출

생성자 함수로 호출

메서드로 호출

[[Call]] callable: 호출할 수 있는 함수 객체

[[Construct]]constructable: 인스턴스를 생성할 수 있는 함수 객체. non-constructor이면 .prototype이 undefined

  constructor prototype super arguments
일반 함수 O O X O
메서드 X X O O
화살표 함수 X X X X

26.2 메서드

축약 표현으로 정의된 함수=> non-constructor

function 키워드 생략하여 정의

 

[[HomeObject]]는 자신을 바인딩한 객체를 가리키는 내부 슬롯.

=> __proto__: 

__proto__에 할당된 객체를, super 키워드로 수퍼클래스의 메서드 참조 가능

 

26.3 화살표 함수

26.3.1 화살표 함수 정의

26.3.2 화살표 함수와 일반 함수 차이

(1) 화살표 함수: non-constructor=> 인스턴스 생성 불가능

(2) 중복된 매개변수 이름을 선언할 수 없다. ↔ 일반 함수는 가능

function normal(a,a) { return a+a; } 
const arrowFunc = (a,a)=> a+a; //에러

(3) 화살표 함수는 함수 자체의 this, arguments, super, new.target 바인딩을 갖지 않는다.

=> 스코프 체인을 통해 상위 스코프의 this, arguments, super, new.target을 참조

 

26.3.3 this

this는 함수가 어떻게 호출되었는지에 따라 동적으로 결정

 

고차함수의 경우,

콜백 함수를 일반 함수로 호출한다면, this는 undefined

 

콜백 함수의 인수로 일반 함수를 전달한 경우 내부에 this를 사용하려면,

(1) const that을 선언 및 할당으로 회피!

add(arr){
    const that = this;
    return arr.map(function(item){
        return that.prefix + ' ' + item;
    })
}

(2) map 함수의 두번째 인수로 this로 사용할 객체를 전달!

(3) bind메서드를 사용

(4) 화살표 함수 사용

화살표 함수는 this 바인딩을 갖지 않아서 상위 스코프의 this를 그대로 참조한다.

=> lexical this

: 함수가 정의된 위치에 의해 결정

 

프로퍼티에 '할당'한 화살표 함수의 this는 스코프 체인 상에서 상위 함수의 this를 참조

즉, 객체 내부에 같은 level로 정의되어 있다고 하더라도 이를 무시하고 상위 스코프를 참조한다.

const counter ={
    num: 1,
    increase: ()=> ++this.num
}

console.log(counter.increase()) // NaN

화살표 함수는 this 바인딩을 갖지 않는다.

=> call, apply, bind 메서드를 사요해도 this를 교체할 수 없다

 

화살표 함수는 this가 참조하는 스코프 문제가 있기 때문에,

메서드를 동적으로 추가하려고 한다면,

(1) 객체 리터럴을 바인딩

(2) 프로토타입을 생성하고(상위 스코프를 생성) constructor 프로퍼티에 생성자 함수를 연결

 

혹은,

클래스 필드 정의 제안을 사용

 

26.3.4 super

화살표 함수는 super 바인딩을 갖지 않는다

따라서, 상위 스코프의 super를 참조

 

26.3.5 arguments

화살표 함수는 arguments 바인딩을 갖지 않는다

따라서, 상위 스코프의 arguments를 참조

=> 따라서, Rest 파라미터를 사용하는 것 권장

 

26.4 Rest 파라미터

26.4.1 기본 문법

(1) 반드시 마지막 순서여야 한다.

(2) 단 하나만 선언 가능

function foo(param1, ...rest){}

function foo( ...rest, param1){} // SyntaxError

function foo( ...rest,...rest2){} // SyntaxError

 

26.4.2 Rest 파라미터와 arguments 객체

 

arguments 객체

유사 배열 객체 => {length: 2, '0': 1, '1':2}

● 함수 내부에서 지역변수처럼 사용 가능

배열 메서드를 사용하려면 객체를 배열로 변환해야 함

Array.prototype.slice.call(arguments)

Rest 파라미터

배열 (유사 배열 객체)

● 함수 내부에서 지역변수처럼 사용 가능

배열 메서드를 사용하려면 객체를 배열로 변환해야 함

 

26.5 매개변수 기본값

인수가 전달되지 않은 매개변수의 값은 undefined

따라서,

(1) 방어코드를 작성하거나

(2) 기본값을 대입

 

Rest 파라미터에는 기본값을 지정할 수 없다.

 

length 프로퍼티는 기본값이 설정되지 않은 매개변수의 개수를 반환