Search

23장 ES6 함수 추가 기능

대분류
언어
서적
소분류
JS DeepDive
주요 레퍼런스
https://velog.io/@hustle-dev/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-262%EC%9E%A5
태그
함수
메서드
화살표함수
this
super
REST
최종 편집 일시
2024/10/27 15:39
생성 일시
2024/02/07 07:59
13 more properties

함수의 구분

ES6 이전의 함수는 동일한 함수라도 다양한 형태로 호출할 수 있었다.
var foo = function () { return 1; }; // 일반함수 foo(); // 1 // 생성자 함수로서 호출 new foo(); // foo {} // 메서드로서 호출 var obj = { foo: foo }; obj.foo(); // 1
TypeScript
복사
ES6 이전의 모든 함수는 일반 함수로서 호출할 수 있는 것은 물론 생성자 함수로서 호출 가능
ES6 이전에 일반적으로 메서드라고 부르던 객체에 바인딩된 함수도 callable이면서 constructor이기 때문에 여러가지 형태로 호출할 수 있었다. --> 콜백함수도 마찬가지
그러나 위와 같이 함수를 여러 형태로 호출하게 되면 실수를 유발하고 성능상에도 좋지 않다.
ES6에서 함수의 사용목적에 따른 3가지 종류로의 구분
ES6 함수의 구분
constructor
prototype
super
arguments
일반 함수(Normal)
O
O
X
O
메서드(Method)
X
X
O
O
화살표 함수(Arrow)
X
X
X
X

메서드

ES6 사양에서 메서드는 메서드 축약 표현으로 정의된 함수만을 의미
const obj = { // 메서드로 정의 foo () { return 1; } // 일반 함수처럼 정의 bar: function () { return 1;} }
TypeScript
복사
foo의 경우 메서드 축약표현으로 작성하였으며 이 메서드는 인스턴스를 생성할 수 없는 non-constructor이다. --> 생성자 함수로 호출X
표준 빌트인 객체가 제공하는 프로토타입 메서드와 정적 메서드 또한 모두 non-constructor
ES6메서드는 자신을 바인딩한 객체를 가리키는 내부 슬롯 [[HomeObject]]를 갖는다. --> ES6 메서드는 super 키워드 사용 가능하지만 이것이 아닌 함수는 내부 슬롯 HomeObject가 없어서 사용 불가능(super 사용 불가)

화살표 함수

표현만 간략한 것이 아닌 내부 동작또한 기존함수보다 간략하며 콜백 함수 내부의 this가 전역 객체를 가리키는 문제를 상위스코프를 가리킴으로써 해결

화살표 함수 정의

const arrow = (x, y) => x + y; const arrow = x => return x; const arrow = () => { ... };
TypeScript
복사
함수 몸체가 하나의 문의라면 {} 생략 가능하고 이 경우, 표현식인 문이 아니면 에러 발생.
{} 안에는 문이 들어감
화살표 함수 또한 일급 객체이므로 고차함수에 인수로 전달할 수 있는데, 이 경우 일반적인 함수 표현식보다 표현이 간결하고 가독성이 좋음.

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

1.
화살표 함수는 인스턴스를 생성할 수 없는 non-constructor이다. --> prototype 프로퍼티와 프로토타입 생성 X
2.
중복된 매개변수 이름을 선언 X --> strict mode에선 일반함수도 중복된 매개변수 사용 불가
3.
화살표 함수는 함수 자체의 this, arguments, super, new.target 바인딩을 갖지 않는다. --> 스코프 체인을 통한 상위 스코프의 요소 참조

this

콜백함수가 일반함수라면 그 안의 this는 전역 객체를 가리키고, class 내부라면 자동적으로 strict mode가 적용되어 undefined를 가리킨다.
이 경우 this를 제대로 바인딩 시키기 위해서는 const that = this를 사용하거나 this를 함수의 인수로 전달하거나, bind메서드를 사용하여야 하는데 화살표 함수를 사용하면 그런거 없이도 간단하게 해결이 가능하다!
화살표 함수는 함수 자체의 this 바인딩을 갖지 않고 따라서 화살표 함수 내부에서 this를 참조하면 상위 스코프 this를 그대로 참조한다. 이를 lexical this라 한다. --> 메서드를 통한 this 바인딩 또한 불가능한 이유
const counter = { num: 1, increase: () => ++this.num }; console.log(counter.increase()) // NaN
TypeScript
복사
전역에서 정의된 객체의 프로퍼티에 할당한 화살표 함수안의 this는 전역을 참조
프로토타입 객체의 프로퍼티에서의 화살표 함수또한 동일한 문제가 발생하므로 동적할당 할때 일반함수를 사용하거나, 객체 리터럴을 바인딩하고 프로토타입의 constructor 프로퍼티와 메서드 축약표현을 사용
클래스에서 클래스 필드에 정의한 화살표함수는 결국 인스턴스 메서드가 되기 때문에 메서드 축약표현을 사용하여 정의하는 것이 좋음.

super

화살표 함수는 함수 자체 super 바인딩을 갖지 않아서 화살표 함수 내부에서 super 참조 시 this와 마찬가지로 상위 스코프의 super를 참조
--> 만약 클래스 필드에서 정의가 된 화살표 함수라면 constructor 내부의 super 바인딩을 참조하는 것과 동일

arguments

자체적인 arugments 바인딩을 갖지 않고 상위 스코프의 arugments를 참조

Rest 파라미터

기본 문법

REST 파라미터는 함수에 전달된 인수들의 목록을 배열로 전달받음.
function foo(...rest) { console.log(rest); // [1, 2, 3, 4, 5] } foo(1, 2, 3, 4, 5);
TypeScript
복사
하나의 Rest 파라미터만 사용 가능
함수 정의 시 선언한 매개변수의 개수를 나타내는 length 프로퍼티에 영향 X

Rest 파라미터와 arguments 객체

arguments 객체는 유사배열 객체여서 배열 메서드를 사용하려면 배열로 변환해야하지만 rest 파라미터의 경우 배열로 인수를 직접 전달 받기 때문에 배열 메서드 사용 시 배열로 변환할 필요X
화살표 함수는 arguments를 갖지 않으므로 무조건 rest 파라미터 사용해야함!(가변 인자 함수 구현 시)

매개변수 기본값

인수가 전달되지 않으면 기본값이 undefined이기 때문에 예기치 않은 결과를 초래할 수 있어서 다음과 같이 사용
function sum (x = 0, y = 0) { return x + y; } console.log(sum(1, 2)); // 3 console.log(sum(1)); // 1 console.log(sum.length); // 0
TypeScript
복사
rest 파라미터에는 기본값을 지정할 수 없다. function foo(...rest = []) {...} X
length 프로퍼티와 arugments 객체에 아무런 영향 X