본문 바로가기

Study/VanillaJS

[개념잡기] 함수형 프로그래밍 - (6) call

[개념잡기] 함수형 프로그래밍 - (6) call

서론

이번 포스팅에서는 참고하고 있는 강의에서는 설명하고 있지만 다른 코드로 대체한 call() 메서드에 대해 알아보도록 하자

함수형 프로그래밍

유사 배열

javascript 에서 배열처럼 생겼지만 배열의 메서드를 못쓰는 배열을 말한다. 대표적인 유사배열은 arguments 가 있다.

const example = function(){
  console.log(arguments)
  console.log(arguments.forEach(el => {
    console.log(el)
  }))
}

example(1, 2, 3)

======= 출력 =======
Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
library.js:91 Uncaught TypeError: arguments.forEach is not a function
    at example (library.js:91)
    at library.js:96

보시다시피 유사배열은 Array 의 기본 메서드 (forEach 등등)를 사용하지 못한다.

call 메서드

유사 배열에 Array 메서드를 사용할수 있게 도와주는 Function 메서드인 call 이 있다.

기존에 작성했던 reduce 함수 코드를 가지고 이해해보자

const _reduce = function(list, iter, memo) {
  if(arguments.length == 2) {
    [memo, ...list] = list // 여기
  }
  _each(list, (val) => {
    memo = iter(memo, val)
  })
  return memo
}

원래 강의에서 저부분을 다른 방법으로 구현한다.
Array의 기본 메서드인 slice를 변수에 담아 call 메서드를 이용하여 사용한다.

call 메서드를 사용하여 작성해 보겠다.

var slice = Array.prototype.slice

const _rest = function(list, num) {
  return slice.call(list, num || 1)
}

const _reduce2 = function(list, iter, memo) {
  if(arguments.length == 2) {
    memo = list[0]
    list = _rest(list)
  }
  _each(list, (val) => {
    memo = iter(memo, val)
  })
  return memo
}

_rest 함수에서 slice 함수를 call 하여 배열을 자르는 것을 볼 수 있다. 저렇게 call을 이용해 이미 구현 되어있는 메서드나, 직접 생성한 함수를 실행 시킬 수 있다.

Array.from()

ES6 부터는 유사 배열을 배열로 바꿀수 있게 되었다. 바로 Array.from 을 사용하는 것인데 직접 코드를 통해 설명해 보겠다.

대표적인 유사배열은 arguments(화살표 함수의 등장으로 잘 쓰이지 않고 있다.) 말고도 document.querySelectorAll() 로 생성된 배열 또한 유사배열이다. 위 코드로 생성된 배열에 slice 메서드를 사용하면 error 가 발생한다.

Array.from() 메서드는 배열형태를 가지고 있는 객체(유사배열) 을 Array 객체로 만들어 준다.

var nodes = document.querySelectorAll("*")

console.log(nodes)
// NodeList(9) [html, head, meta, meta, meta, title, script, body, script]
Array.isArray(nodes)
// false

nodes = Array.from(nodes)
// (9) [html, head, meta, meta, meta, title, script, body, script]

Array.isArray(nodes)
// true