본문 바로가기
책을 읽어봅시다/무던한 개발자를 위한 모던한 자바스크립트

[무던한 개발자를 위한 모던한 자바스크립트]함수와 함수형프로그래밍

by upswp 2022. 2. 17.
안녕하세요 Samuel 입니다 : )

해당 책의 내용중 저에게 필요한 일부를 메모하는 방식으로 작성하였으며( +@ 느낀점도 살짝살짝 적어봤어요! ), 추가적으로 구글링과 공식문서를 참고해서 글을 작성해봤습니다.

한빛미디어 <나는 리뷰어다> 활동을 위해서 책을 제공받아 작성된 서평입니다.


함수와 함수형 프로그래밍

함수형

자바스크립트는 함수형 프로그래밍 언어이다. 함수는 값으로 취급하며 이를 변수로 저장하거나, 인수로 전달하거나, 다른 함수의 결과로 반환할 수 있다. 예를들어 다음은 average 함수를 변수에 저장하는 코드다.

let f = average

다음처럼 함수를 호출한다.

let result = f(6,7)

f(6 , 7)이라는 표현식을 실행할때 f는 함수로 인식되며 인수 6과 7을 이용해 이 함수를 호출한다. 다음과 같이 변수 f에 다른 함수를 저장할 수 있다.

f = Math.max

f(6 , 7)을 호출하면 이번에는 Math.max의 결과를 호출하게 되며 결과는 7이된다.

<aside> 💡 위와 같이 작업을 진행하며 메서드 자체를 가져와서 변형하면서 사용해야할 경우 함수 자체를 변수로 잡아 처리를 하게 된다면 효율적인 함수형 프로그래밍이 가능할 것 으로 보인다.

</aside>

이번에는 함수를 인수로 전달하는 예제를 살펴보자. arr는 배열이라 가정하자.

arr.map(someFunction)

이 코드는 someFunction을 배열의 모든 요소에 적용한 다음, 결과를 모은 배열(기존 배열은 변경하지 않음)을 반환한다.

result = [0, 1, 2, 3].map(Math.sqrt)

map 메서드 처럼 다른 함수를 소비하는 메서드를 고차함수(higher-order function)이라고 부른다.

 

💡 // TODO

curring, thunk, partitial apply란?

함수 리터럴(function literal)

function multiplyBy10(x) {return x * 10}
result = [0,1,2,4].map(multiplyBy10)

한번만 사용할 함수를 새로 선언하는 부분은 낭비로 느껴진다. 이 부분을 해결하기 위해 함수 리터럴을 활용한다.

result = [0, 1, 2, 4].map(function(x) {return 10 * x})

이름이 없는 function 을 선언하여 안쪽에 넣어주었다. 함수 리터럴은 동작을 정의하는 값이며 이 값을 map 메서드로 전달한다.

이름이 없는 배열 리터럴 [0 , 1, 2, 4]처럼 함수 리터럴도 이름을 갖지 않는다. 함수에 이름을 부여하고 싶을때는

const average = function (x, y) {return (x+y) /2 }

화살표 함수(arrow function expression)

const average = (x,y) => (x + y)/2

화살표 왼쪽에서 매개변수를 제공하고 오른쪽에서 값을 반환한다. 매개변수가 한개라면 다음과 같이 괄호를 생략할 수 있다.

const multiplyBy10 = x => x * 10

매개 변수가 없으면 빈 괄호 쌍을 사용한다.

const dieToss = () => Math.trunc(Math.random()*6)+1

dieToss는 숫자가 아니라 함수다. dieToss()를 호출할때마다 1에서 6까지 숫자 중 임의의 숫자를 얻는다.

화살표 함수의 코드가 조금 더 복잡한 상황이라면 본문을 블록문으로 구현한다. return 키워드로 값을 블록 밖으로 반환한다.

const indexOf = (arr, value) => {
	for (let i in arr) {
		if(arr[i] === value) return i
	}
	return -1
}

객체 리터럴을 반환하는 화살표 함수를 구현할 때는 괄호로 객체를 감싸야한다. 그렇지 않으면 중괄호 블록으로 인식한다.

const stats = (x , y) => ({
	average: (x + y) / 2
	distance: Math.abs(x - y)
})

💡 // TODO

클로저?

클로저와 람다의 차이점은?

클로저(페이지링크 차후 업로드 예정 다음 스터디 주제 작성중⚠️)

조금 아쉬웠어요.

해당 내용을 이해하기에는 내용이 책에 조금 빈약하게 들어가있어서 다른 책과 구글링을 통해서 내용을 업로드해볼 예정입니다. 


엄격모드

'use strict'

주성을 제외한 파일의 가장 윗부분에 위의 코드를 입력하면 엄격모드를 활성화 시킬 수 있다.
( 작은 따옴표 대신 큰따옴표를 사용할 수 있다. )

엄격모드의 핵심은 다음과 같다.

  • 미리 선언하지 않은 변수에 값을 할당하면 전역 변수를 만드는 대신 오류로 처리한다. 모든 변수는 let, const, var등으로 선언해야 한다.
  • NaN이나 undefined 같은 읽기 전용 프로퍼티에 값을 할당할 수 없다. (하지만 안타깝게도 같은 이름을 갖는 지역변수를 선언하면 전역 프로퍼티가 가려진다. )
  • 함수는 스크립트나 함수의 가장 최상위 수준에만 선언할 수 있고 중첩된 블록안에는 선언할 수 없다.
  • 유효현 식별자에만 delete 연산자를 사용할 수 있다. 예를들어 delete pareInt는 문법 오류다. delete ‘Hello’.length와 같이 ‘설정할 수 없는’프로퍼티에 delete를 사용하면 런타임 오류가 발생한다.
  • 함수 매개변수를 중복 (예를들어 function average(x,x)으로 가질 수 없다. 물론 함수 파라미터를 이처럼 정의하는 사람은 없지만 비 엄격모드에서는 가능하다.
  • 0을 앞에 붙여 8진수 리터럴을 만들 수 없다. 010은 팔진수 10(10진수로는 8)이 아니라 문법 오류다. 8진수 10은 0o10처럼 표현해야한다.

 

참고문서

무던한 개발자를 위한 모던한 자바스크립트