Last active
December 13, 2015 21:19
-
-
Save nephilim/4976804 to your computer and use it in GitHub Desktop.
Created to demonstrate one of possible problems with a sample code in chapter four of the book Javascript Patterns. For more information, refer to an example on page 100 of the book
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function curry(fn) { | |
| var slice = Array.prototype.slice; | |
| var args = slice.call(arguments); | |
| // curry.call(obj)의 형태로 호출했을 경우 | |
| var self = this; | |
| if (typeof(args[0]) != "function") { | |
| // 예외 처리 | |
| throw { name: "ArgumentException", | |
| message: "First argument should be a function" }; | |
| } | |
| called_args = args.slice(1); | |
| return function() { | |
| // 명시적으로 self를 지정하지 않고 | |
| // this를 사용하면 반환된 함수를 사용하는 scope을 따라간다. | |
| args = slice.call(called_args).concat(arguments); | |
| // 책에 있는 예제와 달리 captured variable인 self를 전달함 | |
| return fn.apply(self, args); | |
| }; | |
| } | |
| var obj = { | |
| base: 10, | |
| add_to_base: function() { | |
| // 인자 개수에 상관없이 동작하느라 좀 길지만, | |
| // 결국 base에 인자를 모두 더하는 함수 | |
| var args = Array.prototype.slice.call( arguments, 0); | |
| sum = this.base; | |
| for(var i =0; i < args.length; i++) { | |
| sum += args[i]; | |
| } | |
| return sum; | |
| }}; | |
| /* | |
| var add_to_hundred = curry.call(obj, obj.add_to_base, 90) | |
| add_to_hundred(100) | |
| > 200 | |
| // 책의 예제는 다음과 같아서 실패함 | |
| var add_to_hundred = curry.call(null, obj.add_to_base, 90) | |
| add_to_hundred(100) | |
| > NaN | |
| */ |
outsideris
commented
Feb 19, 2013
Author
아닌자 님의 코드는 다음과 같이 obj의 문맥을 적용할 수 있습니다.
obj.add_to_base.curry(20, 30).call(obj, 40)
// 100
obj.base60 = obj.add_to_base.curry(20, 30)
obj.base60(40)
// 100
개인적으로는 커리된 함수를 obj의 멤버로 지정하는 두 번째 방법이 좋아보입니다. 하지만 해당 문맥에 넣지 않으면 안되고, call/apply를 적용하는 건 애초에 불가능합니다. 이건 var fn = this 때문이기도...
this를 사용하는 레식옹의 코드도 나쁘지 않기는 한데... 어쨌던 제 방법에 레식옹의 function prototype을 적용하는 것은 생각해보지 못했네요, 책의 예제를 벗어나서 생각해본 건 아닌데... (부들부들)
Author
@outsideris 그래도 지구는 돈다 궁시렁 궁시렁 @McTenshi 도와죠
초대 감사합니다. ㅋㅋ
"아닌자"라니 "Non-person" 같군요.
레식옹의 방법은 function의 prototype으로 하지 않았을 때 첫번째 인자가 function인지 검사하는 로직을 구조적으로 해결했다는 것이 참 아름답군요.
그나저나 두 코드가 비슷한걸 보니 네피림님에게서도 닌자의 향기가...
마지막줄에.. +1 입니다.
@nephilim 닌자님의 인술이 더 강력했습니다...
Author
@outsideris 전 닌자가 아니에욧! 어쨌건 제 주장을 이해해 주시니 감사. (하지만 레식옹 코드 보자마자 이야기 했는데... 역시 보고 있지 않았;;; )
@McTenshi '아-닌자'로도 '아닌-자'로도 읽히는 군요. 두 개의 별명을 한 큐에!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment