본문 바로가기

자바스크립트

[Javascript] - 자바스크립트 배열 고차 함수 직접 구현해보기

 

* 시작하면서

평소에  개발과 알고리즘 문제를 풀면서  자바스크립트 배열의 고차함수들은 어떤 원리로 동작하는지  호기심이 있었다

단순히 built-in으로 존재하다보니 사용법만 익힌 다음 사용하기만 했는데  이번 기회로 MDN과 같은 여러 자료를 참고했고

직접 구현도 해보면서 배열의 고차함수들이 어떤 원리로 동작하는지 파악했다  구현하면서 개인적으로 신경 썼던 점은 기존의 배열 메서드를 최소화해서 직접 짜보는 것이였다  이번 포스팅에서는 map, every, filter만 작성했지만 나머지 고차함수들도 다뤄볼 예정이다 참고로 기본 자바스크립트 배열 고차함수들과 100% 같다고 확신할 수는 없다 ㅎㅎ

 

1. map

 

 

 

 

map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환한다.

 

 

직접 구현한 전체적인 mapFunc 코드이다

 

간단하게 살펴보면 앞부분에서 오류 처리 코드를 작성해서 this가 null 이거나 인자로 받는 callback이 함수가 아닐 경우 TypeError를 던지도록 작성하였다.

 

또한 arguments의 길이가 1이상일 경우

 

즉 mapFunc  함수의 2번째 인자로  callback을 호출할 때 사용할  this를 인자로 넘겼을 때 bindThis  변수에다 thisArg를 할당하는데 왜 이렇게 했는지는 밑에서 에러 호출 예제를 살펴보도록 하겠다.

 

그 다음은 for 반복문을 통해 호출 배열의 각각의 요소마다 callback 함수를 적용해 result라는 배열로 할당하는 내용이다

 

이때 this 를 명시적으로 바인딩할때 사용하는 call함수를 사용했다  call함수는 첫번째 인자로 바인딩 할 this를 인자로 넘기고 그 이후 인자부터는 함수가 호출될 때 넘겨주는 인자들이다

 

마지막으로 map은 새로운 배열을 반환하기 때문에 각 요소에 callback 함수 호출 결과를 담은 result를 반환했다.

 

map 일반적인 호출 예제

 

 

 

map 에러 호출 예제

 

 

위 예제는 당연히 callback이 함수가 아니기 때문에 TypeError를 호출한다.

 

 

위 예제에서도 인스턴스 생성 후에 add메서드를 호출하면 TypeError 가 발생하는 것을 확인 할 수 있다

이게 call, thisArg, bindThis를 넣은 이유다

 

지금 mapFunc의 callback으로 일반 함수를 넣고 있는데 thie는 호출 방식에 따라 동적으로 바인딩된다.

 

 

this는 일반 함수에서 호출하면 전역 객체를 가리킨다 하지만 엄격모드에서는 this가 전역 객체를 가리키지 않고 undefined를 가리키는데 클래스 내부의 모든 코드에서는 엄격 모드가 암묵적으로 적용된다.

 

따라서 위 mapFunc에서도 엄격 모드가 적용되서 this가 undefined에 바인딩 되는 것이다.

 

그래서 위 예제의 오류의 근본적인 원인을 살펴보면 add 메서드 내부인 1번에서 this와 mapFunc의 인자로 들어가는 callback 함수 내부 (2)에서 this가 서로 다르기 때문에 발생하는 것이다.

 

이런 오류를 해결하기 위해 mapFunc의 두번째 인자로 thisArg를 받습니다.

 

 

 

이렇게 mapFunc의 2번째 인자로 this를 넣으면 add 메서드 시점의 this를 mapFunc의 두번째 인자로 넘겨 call을 통해 명시적으로 add메서드의 this를 바인딩해서 오류를 해결할 수 있다.

 

2. filter

 

 

filter() 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환한다.

 

 

기본적인 구조는 mapFunc와 다를게 없지만 filter 같은 경우는 콜백함수를 호출했을때 해당 조건식을 통과한 현재 요소를 모아 새로운 배열을 반환해야 한다는 점이다

 

그리고 스택처럼 result 배열에 차곡차곡 쌓아야 하기 때문에 current라는 변수를 선언해 사용했다.

 

사실 단순히 push를 사용해도 됐지만 배열 메서드를 최소로 사용해 구현하려고 했기 때문에 result의 배열의 현재 인덱스를 의미하는 current 변수를 사용했다.

 

그외에는 크게 다를 바 없다 .

 

filter 일반적인 호출 예제

 

 

위 예제처럼 콜백 함수의 조건을 충족하는 요소들만 모아 새롭게 배열을 반환하는 것을 확인할 수 있다.

 

 

3. every

 

 

every 메서드는 배열 안의 모든 요소가 주어진 판별 함수를 통과하는지 테스트한다  Boolean값을 반환한다.

 

 

마찬가지로 map과 filter와 크게 다르지는 않지만 차이점이라면 every는 새로운 배열을 반환하는 것이 아닌 모든 요소가 콜백함수의 조건을 모두 충족하는지 여부를 반환하기 때문에 result라는 배열은 필요없어 제거했다.

 

따라서 callback 을 호출하면서 value가 false면 false를 리턴하고 for문이 모두 완료됐다면 모든 요소가 콜백 함수 조건에 충족한다는 뜻이기 때문에 true를 반환한다.

 

 

every 일반 예제 호출 예제

 

 

배열의 요소들이 콜백함수의 조건을 모두 충족하면 true 그렇지 않으면 false를 반환하는 것을 확인 할 수 있다

이상으로 포스팅을 마친다.

'자바스크립트' 카테고리의 다른 글

[Javascript] - 내장 클래스 확장하기  (0) 2023.04.16
[Javascript] - async와 await  (0) 2022.12.20
[Javascript] - Promise 체이닝  (0) 2022.12.16
[Javascript] - Promise  (0) 2022.12.07
[Javascript] - 콜백  (0) 2022.11.20