함수형 자바스크립트 기본

함수형 패러다임을 자바스크립트에 적용할 때에 알면 좋은 Javascript의 기본 문법과 배경 지식을 설명한 글이다.

자바스크립트와 타 언어들간의 함수형 프로그래밍 지원의 차이

Javascript에는 없는 함수형 언어의 특징

  1. 순수 함수 강제 (side effect를 발생시키는 표현식을 허용하지 않음)
  2. 불변성 강제 (변수라고 부르지만, 상수. 객체까지도.)
  3. 재귀 강제 (반복문 미지원)

아무래도 Javascript는 멀티 패러다임이라 함수형 패러다임만 지원하는 언어에 비해서는 제약이 덜할 수 밖에 없을 것이다.

Javascript에서 이를 극복하는 방법

  1. eslint 규칙 사용으로 부분적으로 극복.
  2. ImmerJS 등의 라이브러리 도입
  3. 함수형 프로그래밍에 익숙해진다면, 괜찮을 것. (1과 마찬가지로 eslint 규칙 도입 등.)

Javascript 런타임들이 대부분 꼬리 재귀 호출 최적화를 지원하지 않기 때문에, 재귀가 타 함수형 언어에 비해 성능이 낮을 수 밖에 없다.

꼬리 재귀 호출 최적화는 재귀 호출이 함수의 마지막에서 발생하는 경우에 적용된다. 컴파일러가 자동으로 재귀를 반복문으로 치환한다. 덕분에 스택 프레임을 1개만 사용한다.

Javascript의 장점

  1. 다른 모든 함수형 언어는 학습 곡선이 높다. 누구나 이해하고 사용할 수 있다고 하기 힘들다.
  2. ES6+부터 함수형 지원이 좋은 편이다.
  3. 타 함수형 언어들에 비해 시장이 크고, Production-level Application 구축이 용이하다.

함수 실행(call, apply)과 인자(arguments), 점(.) 다시 보기

Javascript의 함수 안에서는 arguments 객체와 this 키워드를 사용할 수 있다.

※ 화살표 함수에서는 arguments를 사용할 수 없다.

1
2
3
Uncaught ReferenceError: arguments is not defined
at hi (<anonymous>:1:37)
at <anonymous>:1:1

arguments 객체

배열과 유사한 Arguments 객체(Arguments(4) [ ‘a’, ‘b’, ‘c’, ‘d’, … ])로 매개변수들이 전달된다.

arguments에 접근하는 시점에 따라 값이 변경될 수 있다. Javascript의 parameter는 변경할 수 있기 때문에, 이를 변경 후 arguments를 찍어보면 다르게 나온다.

1
2
3
4
5
function hello(a, b) {
a = 1;
console.log(arguments);
}
hello('a', 'b'); // Arguments [1, 'b'];

this 객체

obj.prop()으로 호출 시 objthis가 된다. . 좌측의 객체가 항상 this가 된다.

최상단 scope에서 호출하면 기본적으로 window., global.이 생략된 것이기 때문에 thiswindow, global이 된다. (global은 Node.js 환경에서.)

const { prop } = obj; prop(); 하면 propobj에 속해있음에도 불구하고 thiswindow, global이 된다.

Function.prototype.call

this 객체를 지정해서 함수를 호출할 수 있다.

1
2
3
4
5
6
7
8
const obj = {
thisIs: 'obj',
};
function hello(a, b) {
console.log(this);
}
// 매개변수는 가변 매개변수여서 개수 제한 없이 전달 가능하다.
hello.call(obj, 'a', 'b'); // { thisIs: "obj" }

Function.prototype.apply

call과 다른 점은 매개변수를 배열과 유사한 객체로 넘겨야 한다는 점이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
const obj = {
thisIs: 'obj',
};
function hello(a, b) {
console.log(this);
}
// 매개변수는 배열과 같은 객체로 전달하면 된다.
hello.apply(obj, ['a', 'b']); // { thisIs: "obj" }
hello.apply(obj, {
0: 'a',
1: 'b',
length: 2,
}); // { thisIs: "obj" }

함수형 자바스크립트 기본

https://jsqna.com/fjs-3-functional-js-basics/

Author

Seongbin Kim

Posted on

19-09-04

Updated on

21-01-19

Licensed under

댓글