Learn from article 1
Learn from article 2
I’m going to start with a general method of Currization
// Support multiple parameter passing
function progressCurrying(fn, args) {
var _this = this
var len = fn.length;
var args = args || [];
return function() {
var _args = Array.prototype.slice.call(arguments);
Array.prototype.push.apply(args, _args);
// If the number of arguments is less than the original fn.length, the recursive call continues to collect arguments
if (_args.length < len) {
return progressCurrying.call(_this, fn, _args);
}
// After parameters are collected, run fn
return fn.apply(this, _args); }}Copy the code
define
-
The technique of converting a function that takes multiple arguments into a function that takes a single argument (the first argument of the original function) and returns a new function that takes the remaining arguments and returns the result
-
Call a function by passing only one argument, and return a function to receive the remaining arguments and process the result (also known as partial evaluation)
- Original function – takes four arguments and returns the result
- Currization – Receives 1 argument and returns a function
- This function receives the remaining arguments and returns the final result
-
Example: Change a function that passes x and y into two functions, with the outer layer passing x and the inner layer passing y
function curryingAdd(x) {
return function (y) {
return x + y
}
}
Copy the code
application
(1) Parameter multiplexing
// The normal method
function meet(msg, name) {
console.log(name, msg, "!");
}
meet("hello"."Bob");
// Currified encapsulation
function meetCur(msg) {
return function (name) {
console.log(name, msg, "!");
};
}
// Get the method to auto-populate Hello
let helloMeet = meetCur("hello");
helloMeet("Lucy");
helloMeet("Bob");
helloMeet("Jack");
// Get the method to fill goodBye automatically
let byeMeet = meetCur("goodBye");
byeMeet("Lucy");
byeMeet("Bob");
byeMeet("Jack");
Copy the code
(2) Judge in advance
Originally, each call to ON required a check to see if addEventListener was supported,
After currie, you don’t need to make a judgment every time you confirm it at assignment
var on = function(element, event, handler) {
if (document.addEventListener) {
if (element && event && handler) {
element.addEventListener(event, handler, false); }}else {
if (element && event && handler) {
element.attachEvent('on'+ event, handler); }}}var on = (function() {
if (document.addEventListener) {
return function(element, event, handler) {
if (element && event && handler) {
element.addEventListener(event, handler, false); }}; }else {
return function(element, event, handler) {
if (element && event && handler) {
element.attachEvent('on'+ event, handler); }}; }}) ();Copy the code
(3) Bind implementation
<script>
Function.prototype.mybind = function (context) {
let that = this;
// console.log("tha1t", that);
let args = Array.prototype.slice.call(arguments.1);
console.log(args, "args");
return function () {
// console.log(that, "--that", str);
let arr = Array.prototype.concat.apply(args, arguments);
return that.apply(context, arr);
};
};
function tt(. str) {
// console.log(this, "------", str);
return str;
}
let ll = console.log;
console.log(tt.mybind(this.234.234.43) ("00 0 -"));
ll.mybind(this.234.234.43) ("00 0 -")
</script>
Copy the code
(4) Delayed execution
The following code, as long as the argument keeps passing in, does not execute the processing result but receives the argument and returns the function.
When no more arguments are passed in, all previously received arguments are used for execution and the result is returned
var curryScore = function (fn) {
var allScore = []; // Used to access a single value for each input
// These are used for preprocessing
return function () {
if (arguments.length === 0) {
// fn is executed when no more arguments are passed
fn.apply(null, allScore);
} else {
// The parameters passed in are saved
allScore = allScore.concat([].slice.call(arguments)); }}; };var result = 0;
// addScroe returns a function
var addScore = curryScore(function () {
//fn
for (var i = 0; i < arguments.length; i++) {
result += arguments[i]; }}); addScore(3);
console.log(result); / / 0
addScore(3);
console.log(result); / / 0
addScore(3);
console.log(result); / / 0
addScore();
console.log(result); / / 9
Copy the code
General method of encapsulation
- The complete, generic, encapsulation of a function
parsing
// Support multiple parameter passing
function progressCurrying(fn, args) {
var _this = this
var len = fn.length; // The number of parameters in the fn declaration
var args = args || []; // set args to []
return function() {
// Gets the parameters passed in later, rounding them into the array
var _args = Array.prototype.slice.call(arguments);
// Integrate the previously passed parameter with the passed parameter
Array.prototype.push.apply(args, _args);
// If the number of arguments is less than the original fn.length, the recursive call continues to collect arguments
if (_args.length < len) {
// that is, return is still an append () executable.
return progressCurrying.call(_this, fn, _args);
}
// After parameters are collected, run fn
return fn.apply(this, _args); }}Copy the code
exercises
- Simplify the problem
// Implement an add method that implements the following results
//(Simplified the online interview question)
console.log(add(1) (2) ());/ / 3
console.log(add(1.2.3) (4) ());/ / 10
console.log(add(1) (2) (3) (4) (5) ());/ / 15
Copy the code
function add(. args) {
letret = []; ret.push(... args);if (args.length == 0) return adder();
function adder(. arg2) { ret.push(... arg2);if (arg2.length === 0) {
let sum = 0;
ret.forEach((item) = > {
sum += item;
});
return sum;
} else {
returnadder; }}return adder;
}
Copy the code
- The original problem
// Implement an add method that satisfies the following expectations:
// add(1)(2)(3) = 6;
// add(1, 2, 3)= 6;
/ / add (1) (2, 3) = 6;
function add() {
var _args = Array.prototype.slice.apply(arguments);
// Every time _add passes an argument, it is saved to _args
_args = _args = _args = _args = _args
var _add = function () {
Array.prototype.slice.apply(arguments).forEach(function (item) {
// Another feature, confirm parameters in advance before final settlement results,
if (!isNaN(item)) { _args.push(item); }});return _add;
};
// Take advantage of the toString implicit conversion feature to implicitly convert when finally executed and calculate the final value returned
// This step solves the problem of adding () and printing the result at the same time
_add.toString = function () {
return _args.reduce(function (x, y) {
return x + y;
});
};
return _add;
}
Copy the code