Refer to the link
The function is currified
meaning
Corey: is the fixed part parameters, function returns a accept the rest of the parameters, also known as part of the calculation function, the purpose is to narrow scope of application, create a targeted stronger function, core idea is to put the multi-parameter incoming function parameters (in part) into the single function, internal back again the next single parameter function (in part), dealing with residual function in turn
Anti-currification: Extend the scope of application by creating a broader function so that a method that is only suitable for a particular object can be extended to more objects
General implementation
// The first implementation
Function.prototype.unCurrying = function() {
const self = this
/ /... The REST method is equivalent to destructuring assignment using ES6 syntax using REST to take an array of incoming arguments, equivalent to arguments REST where the value is an array of all the arguments passed in
return function(. rest) {
return Function.prototype.call.apply(self, rest)
}
}
const push = Array.prototype.push.unCurrying()
/* * 1 adds an unCurrying method to a Function prototype, and saves a method that uses unCurrying while performing it into self * * 2 Use apply to give call the Function that you want to borrow as this, and pass in the subsequent parameter */
// The second implementation
Function.prototype.unCurrying = function() {
return this.call.bind(this)}// The third implementation
function unCurrying(fn) {
return function(tar, ... argu) {
return fn.apply(tar, argu)
}
}
Copy the code
Use anti-Cremation
Function.prototype.unCurrying = function() {
const self = this
return function(. rest) {
console.log(rest, 'uncurrying rest')
return Function.prototype.call.apply(self, rest)
}
}
const push = Array.prototype.push.unCurrying()
~function(. rest) {
console.log(rest, 'before')
push(rest, 4.5)
console.log(rest, 'after')
}(1.2.3)
Copy the code
In fact, anti – Corrification reflects a kind of idea-expanding method’s application scope
Function.prototype.unCurrying = function() {
const self = this
return function(. rest) {
console.log(rest, 'uncurrying rest')
return Function.prototype.call.apply(self, rest)
// Array.prototype.push.call({a: 3}, 4, 5)}}const push = Array.prototype.push.unCurrying()
~function() {
let rest = {a: 3}
console.log(rest, 'before')
push(rest, 4.5)
console.log(rest, 'after')
}(1.2.3)
Copy the code
You can use unCurrying methods as long as they are methods
// call
var call = Function.prototype.call.unCurrying()
function $(id) {
return this.getElementById(id)
}
// call()
call($, document.'demon')
/ problem solving steps are * * * = > Function. The prototype. Call. Apply (Function. The prototype. Call, [$, document, 'demon']) * => Function.prototype.call.call($, document, 'demon') * => $.call(document, 'demon') * => document.getElementById('demon) */
// unCurrying borroys itself
const unCurrying = Function.prototype.unCurrying.unCurrying()
const map = unCurrying(Array.prototype.map)
map({0: 4.1: 'a'.2: null.length: 3}, n= > n + n)
/ * * const map = unCurrying (Array) prototype) map) step * = > Function. The prototype. Call. Apply (Function. The prototype. UnCurrying, [Array.prototype.map]) * => Function.prototype.unCurrying.call(Array.prototype.map) * => Array.prototype.map.unCurrying() * => map = Array.prototype.map.unCurrying() * => map({0: 4, 1: 'a', 2: null, length: 3}, n => n + n) * => Function.prototype.call.apply(Array.prototype.map, [{0: 4, 1: 'a', 2: null, length: 3}, n => n + n]) * => Array.prototype.map.call({0: 4, 1: 'a', 2: null, length: 3}, n => n + n) * => {0: 4, 1: 'a', 2: null, length: 3}.map(n => n + n) * => {0: 8, 1: 'aa', 2: 0, length: 3} */
Copy the code
conclusion
The function is currified
function(arg1, arg2) / /function(arg1) (arg2)
function(arg1, arg2, arg3) / /function(arg1) (arg2) (arg3)
function(arg1, arg2, arg3, arg4) / /function(arg1) (arg2) (arg3) (arg4) Copy the code
The curry
obj.fn(arg1, arg2) // fn(obj, arg1, arg2)
Copy the code
Key knowledge analysis
-
Function.prototype.call.apply(self, rest)
Example:
Math.Max.apply([], [1.2.3]) Copy the code
Apply and replace math with [], then Max and pass [1,2,3]. [1,2,3] flattens to 1,2,3 because of apply
Function. The prototype. Call. Apply (self, rest) process
Function.prototype.call.apply(Array.prototype.push, rest)
Array.prototype.push.call(... rest)
So when passing rest, the object you need to operate on comes first, so call can bind this- rest[0].push(rest.shift(1))
var obj = {a: 3} Array.prototype.push.call(obj, 4.5) / / 2 obj // {0: 4, 1: 5, a: 3, length: 2} var obj = {a: 3.b: 3} Array.prototype.push.call(obj, 4.5) / / 2 obj //{0: 4, 1: 5, a: 3, b: 3, length: 2} Copy the code