Analysis of currying in JavaScript

Source: Internet
Author: User

Analysis of currying in JavaScript
Curry: the name of the source and mathematician Haskell Curry (the programming language Haskell is also named by him ). Curialization is also called partial evaluation. It means to pass parameters to the function step by step. After each parameter is passed, some parameters are applied and a more specific function is returned to accept the remaining parameters, in the middle, multiple layers can be nested to accept some parameter functions until the final result is returned. Therefore, the process of curialization is to gradually transfer parameters, gradually narrow the applicability of the function, and gradually solve the problem. Ke Lihua calculates a sum function by step. Let's look at a simple example var concat3Words = function (a, B, c) {return a + B + c ;}; var concat3WordsCurrying = function (a) {return function (B) {return function (c) {return a + B + c ;};}; console. log (concat3Words ("foo", "bar", "baza"); // foo bar bazaconsole. log (concat3WordsCurrying ("foo"); // [Function] console. log (concat3WordsCurrying ("foo") ("bar") ("baza"); // foo bar baza: concat3Word SCurrying ("foo") is a Function. Each call returns a new Function that accepts another call and then returns a new Function until the result is returned, distribution solution, progressive. (PS: the closure feature is used here.) Now let's take a step further. If more than three parameters can be passed, you can pass any number of parameters. When no parameter is passed, the output result is returned? First, a common implementation: var add = function (items) {return items. reduce (function (a, B) {return a + B}) ;}; console. log (add ([1, 2, 3, 4]); but if you want to multiply each number by 10 and then add it, var add = function (items, multi) {return items. map (function (item) {return item * multi ;}). reduce (function (a, B) {return a + B}) ;}; console. log (add ([1, 2, 3, 4], 10); fortunately, there are map and reduce functions. In this mode, add 1 to each item, then, we need to replace the function in map. Next let's take a look at the implementation of colized: var adder = function () {var _ args = []; return function () {if (arguments. length = 0) {return _ args. reduce (function (a, B) {return a + B;}) ;}[]. push. apply (_ args, []. slice. call (arguments); return arguments. callee ;}}; var sum = adder (); console. log (sum); // Function sum (100,200) (300); // flexible calling method. One or more parameters can be input for one call, and supports the chain call sum (400); console. log (sum (); // 1000 (sum calculation) the adder is colized. Function, which returns a new function. The new function receives new parameters in batches and latencies until the last calculation. The more typical kerized function of General kerized functions will encapsulate the last calculation into a function, and then pass this function as a parameter to the kerized function, which is clear and flexible. For example, if each item is multiplied by 10, we can pass in the processing function as a parameter: var currying = function (fn) {var _ args = []; return function () {if (arguments. length = 0) {return fn. apply (this, _ args);} Array. prototype. push. apply (_ args, []. slice. call (arguments); return arguments. callee ;}; var multi = function () {var total = 0; for (var I = 0, c; c = arguments [I ++];) {total + = c ;}return total ;}; var sum = currying (multi); sum (100,200) (30 0); sum (400); console. log (sum (); // 1000 (calculated only when the call is blank) So sum = currying (multi), the call is very clear, and the effect is brilliant, for example, to accumulate multiple values, you can use multiple values as the sum (1, 2, 3) parameter, or you can support chained call, sum (1) (2) (3) the code above is actually a high-order function. A high-order function refers to a function that operates functions and receives one or more functions as parameters, and return a new function. In addition, it depends on the closure feature to save the parameters entered in the intermediate process. That is, the function can be passed as a parameter. The function can be used as the closure of the return value of the function. The above example has been relatively low. Parameter reuse. When the same function is called multiple times and the majority of parameters passed are the same, the function may be a good candidate for colialization. Dynamically create a function. This can be because a new function is dynamically generated to process the subsequent business after partial calculation results, thus omitting repeated calculation. Alternatively, you can dynamically create a new function by applying a subset of parameters that will be passed in to the function, this new function saves the repeated input parameters (you do not have to upload them each time ). For example, the auxiliary method for adding an event to the event browser is var addEvent = function (el, type, fn, capture) {if (window. addEventListener) {el. addEventListener (type, function (e) {fn. call (el, e) ;}, capture) ;}else if (window. attachEvent) {el. attachEvent ("on" + type, function (e) {fn. call (el, e) ;};}; execute the if... else ..., in fact, you only need to make one decision in a browser, and dynamically generate a new function based on the results after one decision, so you do not have to re-calculate it in the future. Var addEvent = (function () {if (window. addEventListener) {return function (el, sType, fn, capture) {el. addEventListener (sType, function (e) {fn. call (el, e) ;}, (capture) ;};} else if (window. attachEvent) {return function (el, sType, fn, capture) {el. attachEvent ("on" + sType, function (e) {fn. call (el, e) ;};}}) (); in this example, if... else... after judgment, some calculations are completed, and a new function is dynamically created to process the parameters passed in later. This is a typical ke Lihua. Function. prototype. the bind method is also different from the call/apply method for colized applications. The bind method sets the first parameter as the context of function execution, other parameters are passed to the calling method in sequence (the main body of the function does not execute itself, which can be regarded as delayed execution), and a new function is dynamically created and returned, which conforms to the characteristics of Keri. Var foo = {x: 888}; var bar = function () {console. log (this. x );}. bind (foo); // bind bar (); // below 888 is a simulation of the bind function. testBind is created and a new function is returned, in the new function, the function that actually needs to execute the business is bound to the context passed in by the real parameter, and the execution is delayed. Function. prototype. testBind = function (scope) {var fn = this; // this indicates a function that calls the testBind method, return function () {return fn. apply (scope) ;}}; var testBindBar = bar. testBind (foo); // bind foo to delay the execution of the console. log (testBindBar); // Function (visible, after bind, a new Function is returned for delayed execution) testBindBar (); // 888 pay attention to this understanding in prototype.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.