다른 프로그래밍 언어는 함수를 지정된 위치에 만들어야 하지만, 자바스크립트는 '함수도 하나의 자료'라는 개념을 가지고 있어 중간에도 만들 수 있다. 이는 2010년 전후에 등장한 비동기 프로그래밍을 이끌었으며, 자바스크립트의 익명 함수는 문법적 가치를 크게 인정받아 다른 프로그래밍 언어로 전파되었다. 람다 또는 익명함수라는 이름으로 기본 문법에 포함되었다.
콜백 함수
자바스크립트는 함수도 하나의 자료형이므로, 매개변수로 전달할 수 있으며 콜백 함수라고 부른다.
콜백 함수 (1) : 선언적 함수 사용하기


callThreeTimes(print)에 의해 callThreeTimes 함수는 abc(i)가 print(i)가 되고 print(i)가 실행된다.
콜백 함수 (2) : 익명 함수 사용하기


위에선 print() 함수를 따로 만들어 넣었고 이건 매개변수에 직접 함수를 넣었기에 같다.
콜백 함수를 활용하는 함수 : forEach()
forEach() 메소드는 배열이 갖고 있는 함수(메소드)로써 단순하게 배열 내부의 요소를 사용해 콜백 함수를 호출해준다.
> function ( value, index, array) {}


콜백 함수를 활용하는 함수 : map()
map() 메소드 또한 배열이 갖고 있는 함수이며, 콜백 함수에서 리턴한 값들을 기반으로 새로운 배열을 만드는 함수이다.
꼭 value, index, array 3개의 매개변수를 다 쓰지않아도 되며, 필요한 값만 쓰면된다. 아래 코드에선 value값만 써도 된다.


콜백 함수를 활용하는 함수 : filter ()
filter() 메소드 또한 배열이 갖고 있는 함수이며, 콜백 함수에서 리턴한 값이 true인것들만 모아서 새로운 배열을 만드는 함수이다.


화살표 함수
단순한 형태의 콜백 함수를 쉽게 입력하고자 화살표 함수를 사용하며, function 키워드 대신 =>를 사용한다.
> (매개 변수) => { 리턴값 }
내부에서 this 키워드가 지칭하는 대상이 다르다는 등 미세한 차이가 있다.
배열의 메소드와 화살표 함수 / 메소드 체이닝


filter() 메소드는 배열을 리턴하므로 mpa() 메소드를 적용할 수 있고 또한 배열을 리턴하므로 forEach() 메소드를 적용할 수 있으며, 어떤 메소드가 리턴하는 값을 기반으로 해서 함수를 줄줄이 사용하는 것을 메소드 체이닝이라고 한다.
타이머 함수
특정 시간마다 특정 시간 이후에 콜백 함수를 호출할 수 있는 함수를 타이머 함수라고 한다.
| 함수 이름 | 설명 |
| setTimeout(함수 , 시간) | 특정 시간 후에 함수를 한 번 호출합니다. |
| setInterval(함수, 시간) | 특정 시간마다 함수를 호출합니다. |
| clearTimeout(타이머_ID) | setTimeout 함수로 설정한 타이머를 제거한다. |
| clearInterval(타이머_ID) | setInterval 함수로 설정한 타이머를 제거한다. |
타이머 걸기


타이머 취소하기


즉시 호출 함수
여러 웹사이트의 자바스크립트 코드를 보면 익명 함수를 생성하고 곧바로 즉시 호출하는 패턴을 많이 볼 수 있다. 코드가 여러 곳에서 사용되면 변수 이름이 충돌될 가능성이 높다. 변수가 존재하는 범위를 스코프라고 부르며, 스코프는 같은 단계에 있을 때 무조건 충돌이 일어난다.
자바스크립트에서 이러한 스코프 단계를 변경하는 방법은 중괄호를 사용하거나 함수를 사용해서 블록을 만드는 방법이 있다.


이렇게 블록 내부에서 같은 이름으로 변수를 선언하며 변수가 외부 변수와 충돌하지않도록 외부 변수를 가리며, 내부 블록에선 선언한 변수만 볼 수 있다. 이렇게 블록이 다른 경우 내부 변수가 외부 변수를 가리는 현상을 섀도잉이라고 부른다.
최신버전의 자바스크립트에선 블록을 사용해서 충돌을 막을 수 있지만, 구 자바스크립트에선 var 키워드를 사용해야지만 변수 충돌을 막을 수 있다. 지금도 구 버전의 자바스크립트를 지원하는 웹 브라우저(익스플로러)에 대응해야 하는 경우가 많고, Babel 등 최신 버전의 자바스크립트를 구 버전의 자바스크립트로 변경해주는 트랜스파일러도 단순한 블록으로 함수 충돌을 막는 코드는 제대로 변환해주지 못 한다.
그래서 많은 개발자들이 함수 블록을 사용해 문제를 해결하며, 충돌 문제를 해결하기 위해 사용하는 것이므로 함수를 만들자마자 즉시 호출할 수 있도록 다음과 같이 작성해야한다.


엄격 모드
엄격 모드란 use strict라는 문자열을 이용해 사용할 수 있고, 이러한 문자열을 읽어들인 순간부터 코드를 엄격하게 검사한다.




자바스크립트는 오류를 어느 정도 무시하고 넘어가는 것들이 있기에 편하기도 하지만 실수로 이어지기도 한다. 일반적으로 사용하는 것을 추천한다. 즉시 호출 함수를 만들고, 이 블록의 가장 위쪽에서 엄격 모드를 적용하는 경우가 많으며, 이렇게 사용할 시 해당 블록 내부에만 엄격 모드가 적용된다.
익명 함수와 선언적 함수의 차이
while 반복문은 조건을 중심으로 반복할 때 많이 사용되며, for 반복문은 횟수, 배열 등을 중심으로 반복할 때 사용한다.
그런데 익명 함수와 선언적 함수는 사용하는 상황이 비슷하기에 혼자 개발할 땐 자신이 편한 것을 사용하고, 다른 사람들과 개발할 땐 모두가 편하다고 생각하는 것을 사용하면 된다. 다만 최근에는 많은 개발자가 안전 등의 이유로 익명 함수를 선호하는 편이다.
익명 함수의 사용
익명 함수는 순차적인 코드 실행에서 코드가 해당 줄을 읽을 때 생성된다.


위에서 아래로 순차적으로 코드가 실행되면서, 익명 함수라는 변수에 두번째 익명 함수가 할당된다.
선언적 함수의 사용
선언적 함수는 순차적인 코드 실행이 되기 전에 생성된다. 따라서 선언적 함수는 같은 블록이라면 어디에서 함수를 호출해도 상관없다.


1번째 선언적함수가 만들어지고 두번째선언적함수가 덮어졌기에 두번째 함수가 할당되었고 순차적이 아니기에 오류없이 호출이 된다.
선언적 함수와 익명 함수의 조합


선언적 함수가 먼저 만들어지고 그 후 익명함수가 만들어지기에 익명함수로 할당된 모습이다. 함수를 같인 이름으로 덮어쓰는 것은 굉장히 위험하기에 안전하게 사용할 수 있는 익명 함수를 더 선호한다.
블록이 다른 경우에 선언적 함수의 사용
선언적 함수는 어떤 코드 블록을 읽어드릴 때 먼저 생성된다. 블록이 나뉘어진 경우에는 선언적 함수의 실행 흐름을 예측하는 것이 훨씬 힘들어지며 블록이 예상치 못하게 나뉘는 문제 등이 발생할 수 있어 안전을 위해 익명 함수를 더 많이 사용한다.


과거 자바스크립트는 var 키워드를 사용해 변수를 선언했지만 덮어쓰는 문제가 발생하기에 현대에선 let, const 키워드를 사용해 변수와 상수를 선언한다.


선언적 함수가 먼저 할당되기에 오류가 난다.
따라서 한가지로 통일해서 사용하는 것이 오류의 위험을 줄일 수 있고, 통일한다면 익명 함수로 통일해서 사용하는 것이 안전을 위해서 더 편한 선택입니다.
확인 문제
1. 홀수만 추출, 100 이하의 수만 추출, 5로 나눈 나머지가 0인수만 추출하는 프로그램을 만들어보세요.


2. 이전 반복문 부분에서 살펴보았던 다음과 같은 코드를 배열의 forEach 메소드를 사용하는 형태로 변경해보세요.


총정리
콜백 함수는 매개변수로 전달하는 함수를 의미한다.
화살표 함수는 익명 함수를 간단하게 사용하기 위해 () => {} 형태로 쓰여지며, 리턴값만 가지는 함수라면 () => 값 형태로 사용할 수 있다.
즉시 호출 함수란 변수의 이름의 충돌을 막기 위해서 코드를 안전하게 사용하는 방법이다.
엄격모드는 자바스크립트의 문법을 엄격하게 검사해 오류를 줄일 수 있으며, 'use strict'을 맨 상단에 배치하므로 사용할 수 있다.
forEach() : for문을 쓰지않고도 배열 안에 값을 가져올 수 있다.
map() : 콜백함수에서 리턴한 값들을 함수 안에 적어준대로 반환하여 새로운 배열로 만들 수 있다.
filter() : 콜백함수에서 리턴한 값들에 true인 값만 모아 새로운 배열로 만들 수 있다.
'TIL' 카테고리의 다른 글
| 10일차 프로그래밍 기초 - 과제 (0) | 2022.11.18 |
|---|---|
| 10일차 프로그래밍 기초 (0) | 2022.11.18 |
| 4일차 JavaScript 챕터 5 - 함수 (0) | 2022.11.11 |
| 3일차 JavaScript 챕터 4 (0) | 2022.11.10 |
| 2일차 JavaScript 챕터 3 (1) | 2022.11.08 |