본문 바로가기

code-states

[code-states][we-win] 24일차 - underbar (1일차)

 

오늘 작성한 코드들

 

 

오늘은 underbar 에 관한 session 을 진행했다

일단 나도, 이 글을 읽는 누군가도 궁금해 할 것이다, '그래서 underbar 가 뭐지?'

내가 생각하기에는...

JS 를 조금 더 편하게 사용하기 위한 라이브러리인 JS 의 underscore 라이브러리(링크, 클릭 시 이동) 처럼

우리도 한 번 우리 손으로 직접 JS 에서 기본적으로 지원하는 method 들을 만들어보는 시간이었고

그렇기 때문에 그 underscore 와 비슷한 underbar 라고 session name 을 정한 것이 아닐까 한다

뭐 여느 과제가 내게 안 그랬냐만은, 이번 과제 또한 상당히 어려웠다

또 기초가 정말 중요하고, 기초가 부족하다는 걸 잘 느끼고 가는 시간이었다

무엇을 배웠는지를 키워드로 정리하자면

함수 표현식 및 callback function 의 능숙한 활용을 위한 연습 이라고 말하고 싶다

 

 

 

 

 


 

 

 

 

 

예시로, 우리가 흔히 그냥 쓰는 forEach() method(MDN 링크, 클릭 시 이동)

직접 구현해 보는 코드를 가져와봤다

조건은 이러했다

0. parameter 로 collection(array가 될 수도 있고, object 가 될 수도 있다)과 iteration 이라는 함수를 받는다

1. collection parameter 의 경우, 배열과 객체를 다 받을 수 있어야 한다

2-1. collection 이 배열인 경우, 모든 값들에 접근이 가능해야 한다

2-2. collection 이 객체인 경우, 모든 key-value pair 들에 접근이 가능해야 한다

그리고 이 함수의 이름은 _.each,

위의 내용을 고려하여 함수 표현식의 스타일로 나타내는 것

이 가장 첫 번째 과제였다

나의 경우 이런 식으로 작성했다

 

 _.each = function(collection, iterator) {
    //먼저, 배열인 경우를 먼저 고려한다 
    if (Array.isArray(collection)) {
      for(let i = 0; i < collection.length; i++) {
        iterator(collection[i], i, collection);
      }
    }

    //그 다음으로, 객체인 경우를 그 다음에 고려한다 
    else if (typeof collection === "object") {
      for (let key in collection) {
        iterator(collection[key], key, collection);
      }
    } 

  };

 

배열 혹은 객체가 날아올 수 있으니, 먼저 collection parameter 에 대한 type 검증을 했다

collection이 array type 인 경우를 먼저 Array.isArray() 를 통해 확인해 주고

그리고 array type 이 아닌 경우, typeof 를 넣었을 때 객체인지를 확인해 주는 식으로 경우를 나누어 코드를 작성했다

그리고 그 코드 안에는, array 의 경우 collection 의 length, 즉 길이만큼 iteration 을 for loop 으로 돌리고

obejct 같은 경우, collection 의 key, 즉 key 의 갯수만큼 iteration 을 for - in loop 으로 돌렸다

iterator 의 parameter 은 무엇이 올 지 모르나, testcase 를 보면

0순위 ) array 의 경우 각 elements, object 의 경우 각 value 에 대해서 접근한다

1순위 ) array 의 경우 각 index, object 의 경우 각 key 에 대해서 접근한다

2순위 ) array 의 경우 그 array 자체, object 의 경우 그 object 자체에 대해서 접근한다

라는 식으로 나와서, 그냥 iterator 함수의 parameter 를 해당 순위에 맞게 넣어주었다

추가로, 요구사항에 맞게 return 되는 값도 없게끔 설계 하였다

그리고, 사실 여기까진 할만했다

 

 

 

 

 


 

 

 

 

 

그 다음으론 앞서 만든 _.each 함수를 통해, 또 다른 함수를 만들어 보는 것이다

다음 단계는 JS 의 filter method (MDN 링크, 클릭 시 이동) 를 구현하는 것이었다, 앞서 적은 _.each 함수를 통해서...

iteration 을 돌고 return 하는 게 없는 함수를 활용해서 어떻게 return 을 시키는가

누구에겐 정말 기본적인 사항일 수 있겠는데, 내겐 이게 제일 어려웠다

여튼, 이 고민을 기준으로 해서 어떻게 코드를 짜야할지 생각해보았다

   /**
     * TIP: 아래와 같이 `each`함수를 통해 iteration 함수를 구현할 수 있습니다. 앞으로 우리가 구현할
     * iteration 함수에서도 `for` loop를 사용하는 대신, 우리가 작성한 `each` 함수를
     * 사용해서 iteration 함수를 구현해보세요.
     */

    // 테스트 함수를 통과하는 모든 element를 담은 배열을 리턴하세요.
     _.filter = function(collection, test) {
    //위와는 다르게 이미 parameter 로 주어질 function 이 존재하는 상황 
    //해당 상황에서 return 하는 값이 없는 사전 선언한 함수인 _.each 를 어떻게 사용해야하는가?
    //이번 함수를 통한 학습 목표는 callback 스타일을 스스로 더 바꿔보는 것이다 

    //일단 먼저 filter 된 값을 받을 빈 array 를 선언해주었다 
      let filteredArray = [];
   

      _.each(collection, function(item)  {
      //그리고 나서, each 함수를 쓰는데, 바로 위에서 받은 test 함수를 parameter 로 집어넣지 않는다 

        if (test(item)) {
        //이런 식으로 조건문을 만든 뒤, 조건문에 해당하는 경우, _.each 함수 외부에 선언한 return 할 array 에 넣어주고 
          filteredArray.push(item);
      }

    });
    
    //each 함수 밖에서 그 값을 return 해 준다 
    return filteredArray;

  };

 

여기서 고려해야 하고, 활용해야 할 요소는

scope / function as parameter / 함수 표현식

해당 사항을 고려하여 코드를 짰다

약간 신기했던 점은, 지정된 함수에 값을 집어 넣었을 때, 그것이 잘 통과가 되면 true 를 리턴한다는 점이었다

function testFunc(a) {
    return a + 1; 
}

testFunc(1);
//2
Boolean(testFunc(1));
//true

이런 식으로다가

그래서, 위에 적은 것처럼, 함수에 parameter 가 들어가서 잘 통과가 되면

그것의 Boolean value 는 true 가 나온다는 점을 이용하여

0. if 조건문 안에 외부 함수로 부터 받은 parameter 인 test 함수를 사용해

1. "그 test 함수가 통과하면, 내가 위에 선언한 filteredArray 에 통과한 그 인자를 넣어줘" 라고 명령을 걸었고

2. each 함수는 해당 함수가 첫 번째 parameter 인 collection 의 모든 element(이번엔 배열을 받아 이렇게 표현하겠습니다) 에 대해 iteration 을 돌기에

3. 위에 적은 "for loop 을 사용하지 않고 기존에 선언했던 each 를 사용하세요" 에 대한 조건도 만족했다

4. 그리고 모든 elements 중에서 함수에 통과된 elements 만 별도의 배열로 끌어내어 return 하였다

이를 통해서, 위에 적은 문제를 시작할 때의 고민인

"iteration 을 돌고 return 하는 게 없는 함수를 활용해서 어떻게 return 을 시키는가"

"그 함수의 parameter 로 test 하는 함수를 바로 줄 게 아니라, 저런 식으로 함수 표현식을 통해 함수를 새로 짜라!"

라는 나름의 해답을 내리면서... 이번 문제도 마무리 했다

 

 

 

 

 


 

 

 

 

사실 나머지 문제는(part 1의) 해당 사항들의 연속이었다

그래서 포스팅은 정말 문제 해결의 단초가 되는 것을 떠올리는 문제에 대해서 적었고

나머지 문제에 대해선 그냥 올리지 않으려 한다... 또, 굳이 다 적을 필요도 없다고 생각한다

 

여튼 오늘은 이런 식으로 함수를 인자로서 활용하고,

또 callback 구조가 나올 수 있도록 코드를 짜는 고민을 해 볼 수 있는 시간이었다

+ 추가로 검색해 보던 도중, 아무래도 나랑 같은 과정을 겪었던 사람의 글(링크, 클릭 시 이동)이 있어서 링크

나보다 더 깔끔하게 설명하고, 깔끔하게 만든듯 하다

24일차 개발일지, 끝!