[TIL] JS_함수 메소드(apply, call, bind) 정리

devmin·2019년 10월 28일
2

TIL

목록 보기
3/3
post-thumbnail

코드스테이츠 함수 메소드 강의 내용 정리

메소드 기본 개념

apply, call, bind 각 메소드는 아래와 같이 사용할 수 있습니다.

[apply]
작성법 : fn.apply(thisArg, [argsArray])
this 인자를 첫번째 인자로 받고, 두번째 인자로는 배열을 받음
[call]
작성법 : fn.call(thisArg[, arg1[, arg2[, ...]]])
this 인자를 첫번째 인자로 받고, 두번째 인자부터는 배열이 아닌 각 인자로 받음
[bind]
작성법 : fn.bind(thisArg[, arg1[, arg2[, ...]]])
call과 인자 작성법은 같으나, apply, call과 달리 바로 메소드가 실행되지 않음. thisArg를 바인딩하는 역할만 함.

사용 예시

1. apply 메소드 활용

Math.max() 메소드를 사용하면, arguments로 받은 숫자 값 중에서 가장 큰 값을 뽑아줍니다.
하지만, 해당 arguments가 배열로 이루어져 있을 경우에는 바로 값을 뽑을 수 없습니다.(NaN 반환) Math.max()의 argument에는 숫자만 들어갈 수 있기 때문인데요, 이때 .apply를 쓰면 이를 해결할 수 있습니다.

.apply에서는 두 번째 인자로 배열을 받고, 그 배열을 각각의 인자로 배정해서 계산을 가능하게 해줍니다. Math.max 메소드에서는 this 역할이 없기 때문에 첫번째 인자에 들어가는 값은 중요하지 않습니다.

2. call, apply 메소드 활용

call 또는 apply를 이용해 주체가 되는 인스턴스와 메소드의 순서를 바꿀 수 있습니다.

기존의 filter 메소드 사용법array.filter(function())을 보면, filter 메소드는 함수를 argument(인자)로 받고, 이를 앞에 있는 인스턴스인 array에 적용합니다. 이부분을 call과 apply의 arguments에 대입해보면, 첫번째 argument인 thisArg 자리에는 array가, 두번째 argument인 arg 자리에는 함수가 들어갑니다.

저 같은 경우는 개념이 잘 정리되지 않은 상태에서 처음 이 사용법을 만나니 이해가 잘 안갔는데, filter 메소드의 기존 사용법에 각 argument 들을 대입해보니 이해가 되기 시작했습니다.

여기까지만 보면 굳이 인스턴스와 메소드의 순서를 바꿀 이유가 없지만, 이 방법을 사용하면 배열 메소드를 유사 배열(array-like object)에 적용시킬 수 있습니다.

자바스크립트에서 DOM 구조를 이용해 element들을 불러오면, 유사배열이 생기는데요, 아래 이미지는 네이버에서 긁어온 리스트 요소들을 보여주고 있습니다.

naver_li.png

이미지를 보면 알 수 있듯이 긁어온 리스트 요소는 배열이 아닌 "NodeList"로, 유사배열의 형태를 보이고 있습니다. 유사배열의 경우, 기존의 filter, map과 같은 배열 메소드를 사용하지 못하는데요, 이때, call, apply 메소드로 prototype 기능을 빌려쓰면 배열 메소드를 사용할 수 있게 됩니다.

이렇게 prototype 기능을 빌려쓰면 아래처럼 유사배열(NodeList)을 배열처럼 사용해 값을 뽑을 수 있습니다.
naver_lis.png

3. bind 메소드 활용 (특정 함수가 this 값을 바꿔버리는 경우)

Box라는 생성자 함수를 사용해 b라는 인스턴스를 만들었습니다. 여기서 this는 "b"가 되므로, b.printArea() 값은 5000이 나옵니다. 그런데 setTimeout()에 이 메소드를 넣으면 아래와 같은 에러가 발생합니다.

20191028_125118.png

위에서는 "this"가 "b"로 잡혔지만, 이번에는 "this"가 "window"로 잡혀버렸기 때문인데요, 이건 setTimeout() 메소드 자체의 특성 때문에 그렇습니다.

thisproblem.png

mdn에서는 setTimeout() 메소드의 경우, 별도로 this 키워드를 설정하지 않으면, this를 "window"로 받는다고 설명하고 있습니다. 이 상황을 처리하기 위해 bind를 사용할 수 있습니다.

위와 같이 argument를 작성하면, b.printAreathis를 인스턴스 b로 지정할 수 있습니다. 하나 참고해야할 건 setTimeout()에 들어가는 첫번째 argument는 함수 실행이 아니라 함수라는 점인데요, 마지막에 (b)가 들어가서 함수가 실행된 것처럼 보이나, 이는 bind를 하는 방식이 그런 것이므로 함수를 실행한 건 아닙니다.

4. bind 메소드 활용 (커링 함수, Curring function)

커링함수는 "argument(인자) 여러개를 받는 함수"를 argument 몇 개를 미리 채움으로써 더 간단히 만든 함수 입니다. 커링함수는 재사용성을 높여준다는 측면에서 많이 사용되는데요, 예시는 아래와 같은 것이 있습니다.

이러한 커링함수를 bind로도 만들어서 사용할 수 있습니다.

위와 같이 미리 argument를 바인딩 시켜놓으면, 커링함수처럼 계속 불러와 함수를 재사용할 수 있습니다.

지금까지 정리를 해봤는데요, 이렇게 정리를 하면서 조금은 메소드 개념과 가까워진 것 같지만, 실제로 활용해봐야 제대로 습득이 될 것 같네요...!

다음 공부하러 총총...

profile
개발자가 되어가는 중

0개의 댓글