본문 바로가기
JavaScript

[js] 자바스크립트 DeepDive 26장 요약

by Delants 2023. 5. 18.

* 본 내용은 자바스크립트 DeepDive 내용을 참고하여 정리한 것입니다.

 

26장. ES6함수의 추가 기능 (P.469~491)

 

26.1) 함수의 구분... ES6이전의 함수의 활용 (P.469~471)

- ES6이전의 모든 함수는 일반 함수로서 호출할 수 있는 것은 물론, 생성자 함수로서 호출할 수 있다. 즉, callable이면서, constructor이다.

- ES6이전에는 객체에 바인딩된 함수를 생성자 함수로 호출하는 경우가 문법상 허용되었다. 이는 성능면에서 문제를 초래한다.

- ES6이전의 모든 함수는 사용 목적에 따라 명확한 구분이 없으므로, 호출방식에 제약이 없고, 생성자 함수로 호출하지 않아도 프로토타입 객체를 생성한다.

 

 

26.2) 메서드 (P.471~473)

- ES6사양에서의 메서드는 메서드 축약 표현으로 정의된 함수만을 의미한다.

- ES6사양에서 정의한 메서드는 인스턴스를 생성할 수 없는 non-constructor이다.

- 그러므로 ES6사양에서의 메서드에서는 prototype프로퍼티가 없고, 프로토타입도 생성하지 않는다. 

- ES6메서드는 자신을 바인딩한 객체를 가리키는 내부 슬롯 [[HomeObject]]를 갖는다. (25.8.5절 참고)

- ES6메서드가 아닌 함수는 super키워드를 사용할 수 없다.

 

 

26.3) 화살표 함수 (P.474~487)

 26.3.1) 화살표 함수의 정의 (p.474~476)

- 화살표 함수는 다음과 같이 함수 표현식으로 정의해야 한다. 

const multiply = (x, y) => x * y;
console.log (multiply(5,8)); // 40

 

<화살표 함수 몸체의 정의>

- 매개변수가 여러 개인 경우, 소괄호 ()안에 매개변수를 선언한다.

- 매개변수가 한 개인 경우, 소괄호를 생략할 수 있다.

- 매개변수가 없는 경우, 소괄호를 생략할 수 없다.

- 함수 몸체가 하나의 문으로 구성된다면 함수 몸체를 감싸는 중괄호를 생략할 수 있다.

- 다만, 표현식이 아닌 문이라면, syntaxerror가 발생한다.

- 객체 리터럴을 소괄호 ()로 감싸지 않으면 객체 리터럴의 중괄호를 함수 몸체를 감싸는 중괄호로 잘못 해석한다.

- 함수 몸체가 여러 개의 문으로 구성된다면 함수 몸체를 감싸는 중괄호를 생략할 수 없다.

- 화살표 함수도 즉시 실행 함수로 사용할 수 있다.

- 화살표 함수도 일급 객체이므로, Array.prototype.map, Array,prototype.filter, Array.prototype.reduce와 같은 고차함수에 인수로 전달할 수 있다.

 

 26.3.2) 화살표 함수와 일반 함수와의 차이 (p.476~477)

- 화살표 함수는 인스턴스를 생성할 수 없는 non-constructor이다.

- 중복된 매개변수 이름을 선언할 수 없다.

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

 

26.3.3) this (p.477~485)

- this는 화살표 함수가 일반 함수와 구별되는 가장 큰 특징이다.

- 화살표 함수의 this는 콜백 함수 내부의 this가 외부 함수의 this와 다르기 때문에 발생하는 문제를 해결하기 위해 의도적으로 설계된 것이다.

- 여기서 콜백 함수 내부의 this문제란, 콜백 함수의 this와 외부 함수의 this가 서로 다른 값을 가리키고 있기 때문에 error가 발생하는 것을 말한다.

- 이러한 문제를 해결하기 위해 ES5까지는 다음과 같은 방법을 사용하였다.

 

<ES5까지의 콜백 함수 내부의 this문제를 해결하기 위한 방법 // 교재 479페이지 소개>

1) add메서드를 호출한 prefixer객체를 가리키는 this를 일단 회피시킨 후에 콜백 함수 내부에서 사용한다.

2) Array.prototype.map의 두 번째 인수로 add메서드를 호출한 prefixer 객체를 가리키는 this를 전달한다.

참고로, Array.prototype.map은 "콜백 함수 내부의 this문제"를 해결하기 위해 두 번째 인수로 콜백 함수 내부에서 this로 사용할 객체를 전달할 수 있다.

3) Function.prototype.bind메서드를 사용하여 add메서드를 호출한 prefixer객체를 가리키는 this를 바인딩한다.

 

<lexical this // 교재 480페이지~483페이지 소개>

- lexical this란, 화살표 함수는 함수 자체의 this바인딩을 갖지 않으므로 화살표 함수 내부에서 this를 참조하면 상위 스코프의 this를 그대로 참조하는 것이다.

- 화살표 함수를 제외한 모든 함수에는 this바인딩이 반드시 존재한다. (화살표 함수는 this바인딩이 존재하지 않는다.)

- 화살표 함수와 화살표 함수가 중첩되어 있을 경우, 스코프 체인 상에서 가장 가까운 상위 함수 중, 화살표 함수가 아닌 함수의 this를 참조한다.

- 화살표 함수가 전역 함수라면 화살표 함수의 this는 전역 객체를 가리킨다.

- 프로퍼티에 할당한 화살표 함수도 스코프 체인 상에서 가장 가까운 상위 함수 중에서 화살표 함수가 아닌 함수의 this를 참조한다.

- 화살표 함수는 function.prototype.call, function.prototype.apply, function.prototype.bind메서드를 사용해도 화살표 내부의 this를 교체할 수 없다. 다만, 이러한 메소드를 호출할 수 없다는 것은 아니다.

- 메서드를 화살표 함수로 정의하는 것은 피해야 하며, 대신 es6메서드 축약 표현으로 정의한 es6메서드를 활용하는 것이 좋다. 단, 프로퍼티를 동적 추가할 경우, es6메서드 정의를 사용할 수 없으므로 일반 함수를 할당한다.

 

26.3.4) super (p.486)

- 화살표 함수는 함수 자체의 super바인딩을 갖지 않는다. 

- 화살표 함수 내부에서 super를 참조하면 this와 마찬가지로 상위 스코프의 super를 참조한다.

 

26.3.5) arguments (p.486~487)

- 화살표 함수는 함수 자체의 arguments바인딩을 갖지 않는다.

- 화살표 함수 내부에서 arguments를 참조하면 this와 마찬가지로 상위 스코프의 arguments를 참조한다.

- 단, 이 의미는 arguments객체를 사용할 수 있다는 의미는 아니다. 단지 참조만 하며, 화살표 함수 자신에게 전달된 인수 목록을 확인할 수 없고, 상위 함수에게 전달된 인수 목록을 참조하는 것이다.

- 만일 화살표 함수로 가변 인자 함수를 구현해야할 경우, Rest파라메타를 활용한다.

 

 

26.4) Rest파라메타 (P.487~489)

 26.4.1) 기본 문법 (p.487~488)

- Rest파라메타(나머지 매개변수)는 매개변수 이름 앞에 세개의 점 (...)을 붙여서 정의한 매개변수를 의미한다.

- 함수에 전달된 인수들의 목록을 배열로 전달받는다.

// 26.4 rest파라메타
function abc(...rest) {
    console.log(rest);
}
abc(10,30,50); // [ 10, 30, 50 ]

- 일반 매개변수와 Rest파라메타는 함께 사용가능하다.

- Rest파라메타는 마지막 파라메타여야한다.

- Rest파라메타는 하나만 선언할 수 있다.

- Rest파라메타는 함수 정의 시 선언한 매개변수 개수를 나타내는 함수 개수의 lenght프로퍼티에 영향을 주지 않는다.

 

 26.4.2) Rest파라메타와 arguments객체 (p.488~489)

- 함수와 ES6메서드는 Rest파라메타와 arguments객체를 모두 사용할 수 있다. 

- 다만 화살표 함수는 함수 자체의 arguments객체를 갖지 않으므로, 화살표 함수로 가변 인자 함수를 구할 경우 반드시 Rest파라메타를 사용해야 한다.

- 참고로, 가변 인자 함수란, 매개변수의 개수를 사전에 알 수 없는 함수이다.

 

 

26.5) 매개변수 기본값 (P.490~491)

- 매개변수의 개수만큼 인수를 전달하지 않는 경우에도 에러가 발생하지 않는다.

- 인수가 전달되지 않은 매개변수의 값은 undefined이다.

- 이 경우, 의도치 않은 결과가 출력될 수 있으므로 기본값 설정이 필요하다. (이를 방어 코드라고 한다.)

- 기본값은 매개변수에 인수를 전달하지 않은 경우와 undefined를 전달한 경우 유효하다.

- 매개변수 기본값은 lenght프로퍼티와 arguments객체에 아무런 영향을 주지 않는다.

 

기본값은 다음과 같은 과정으로 할당할 수 있다.

x에 10, y에 20이라는 기본값을 할당했다.

첫 번째 console.log는 모든 값이 지정되어 있으므로, 지정된 값에 대한 연산을 수행하는 한편,

두 번째 console.log는 x값만 1로 지정되어 있고, y의 값은 지정되어 있지 않으므로 y인자에 대한 지정값인 20이 대입되어 21이라는 결과가 반환된다.

// 26.5 기본값 할당
function sum(x,y) {
    // 기본값을 할당하는 과정이다.
    x = x || 10;
    y = y || 20

    return x+y;
}

console.log(sum(10, 20)); // 30
console.log(sum(1)); //21

 

 

끝.

 

다음 내용: 자바스크립트 DeepDive 27장 [배열(1)] 요약 (p.492~528)

댓글