https://ko.javascript.info/call-apply-decorators
call/apply와 데코레이터, 포워딩
ko.javascript.info
해당 개념을 공부하면서 과제를 풀이했는데, 풀 수 없더군요.
이해가 미숙한 느낌이 들어서 확실이 배워서 익히고 정리하고자 이 글을 씁니다.
글의 내용 정리
1. 함수의 변경 없이 wrapper함수로 해당 함수를 감싸 기능 추가하기.
기존 함수를 func이라고 쳤을 때, func을 받아와 새 함수(wrapper)를 리턴합니다. 이 함수는 목적에 따라 기존 func을 그대로 수행하거나 다른 기능을 추가해 수행합니다.
2.
wrapper함수로 사용하기 위해 가져온 함수가 어떤 객체의 메서드라면 그냥 받아와서 수행하면 안 됩니다.
wrapper함수는 받아온 메서드의 본 객체를 모르기 때문입니다.
따라서 받아온 메서드를 호출할 때는 " 메서드.call(this, 인자) " 형태로 this를 컨텍스트로 넘겨줘야하는 것입니다.
해당 메서드는 애초에 wrapper함수로 넣어질 때 객체.메서드 형식으로 넣어지기 때문에 위에서 this로 했을 때 점 앞의 객체가 this로써 쓰일 수 있습니다.
3. 여러 인수 전달하기
메서드.call(this, x) => 메서드.call(this, ...arguments) 형태로 만듭니다.
그러면 개수를 아직 모르는 복수 개의 argument들을 받을 수 있습니다. 이 때 arguments는 배열 형태는 아님니다.
4. func.call vs func.apply
두 기능의 동작 방식과 결과는 같습니다. 단 하나의 차이는
앞서 말했듯이 func.call은 독립된 인자들이 묶여 들어가는 것이고,
func.apply는 인자들이 배열로서 넘어가게 됩니다.(엄밀히 말하자면 유사배열 객체)
문법을 보자면
func.call(context, ...args);
func.apply(context, args);
대부분 브라우저에서 apply를 최적화하는 편이기에 apply가 조금 더 빠르다고 합니다.
그리고 2, 3, 4의 내용을 지칭하는게 '콜포워딩(call forwarding)'입니다.
다른 함수에 기존 함수를 전달할 때 "인자와 더불어 컨텍스트를 같이" 전달하는 것!
5. 메서드 빌리기
메서드들이 각자 받고 싶어하는 인자의 형태가 다르기 때문에 그게 다를 경우에는 해당 메서드를 사용하기 힘들 수 있습니다.
이 때 사용하는게 메서드 빌리기라고 합니다.
예제의 상황에서는
1. 서로 다른 인자들을 합치고 싶다.
2. 아 인자 합칠 때는 join이란 메서드가 있었다.
3. join이란 메서드는 배열 메서드인데? 말인즉슨 배열에서 호출할 수 있는 애인데.
4. 내가 가진건 진짜 배열이 아니라 이터러블 객체 / 유사 배열 객체가 아니라 join 쓰면 에러나네? (arguments.join() 에러남)
5. 아 그러면 트릭을 써보자.
5-1. 진짜 배열인데 빈 배열을 기준으로 join을 불러온다. ( [].join 이상 없음)
5-2. [].join 이란 메서드 자체를 함수로 인식해 여기에 call을 한다. ([].join.call(arguments)) 그러면 arguments를 컨텍스트로 여기고 그 상태로 [].join을 arguments에 있는 요소만큼 반복해 호출하며 원하는 작업을 완료하는 것.
6. 데코레이터와 함수 프로퍼티
대체로 데코레이터는 함수를 건드리지 않고 기능을 추가할 수 있다는데에서 재사용성이 좋은 기능입니다.
하지만, 경계하며 사용해야할 상황이 있었습니다.
원본 함수에서 자신만의 프로퍼티가 있을 때, 데코레이터는 이것에 접근하기 애매합니다. 이럴 때는 유의하면서 사용해야한다고 합니다.
거의 본문의 내용을 그대로 익히는 수준의 글입니다. 하지만 스스로의 언어로 정리하니 확실히 그냥 읽을 때보다 머리에 그림이 잘 그려진 것 같습니다. 해당 개념은 직적 코딩하며 해당 문제를 쓰게 되면 와서 덧붙이겠습니다.
'Thing about programming > Web' 카테고리의 다른 글
[CSS] SASS 그리고 SCSS (0) | 2022.07.26 |
---|---|
Fetch: Abort (0) | 2022.07.25 |
Fetch: Download Progress (0) | 2022.07.25 |
[HTML] HTML data-* 속성 / dataset Javascipt (0) | 2022.07.24 |
[CSS] textContent vs innerText vs innerHTML (0) | 2022.07.15 |