CNC machine decryption

High-level CNC machine tool decryption functions are functions that operate on other functions, which can be used as parameters or by returning them. In simple terms, a higher-order function is a function that takes a function as a parameter or returns a function as an output.
For example, Array.prototype.map, Array.prototype.filter, Array.prototype.reduce are some higher-order functions.
Welcome to read other JS series articles
JS basic summary (1)
-data type JS basic summary (2)-prototype and prototype chain
JS basic summary (3)-scope and closure
JS basic summary (4)-this Point and call / apply / bind
JS basic summary (5)-JS execution mechanism and EventLoopd
tail call and tail recursive
tail call (Tail Call) is an important concept of functional programming. It is very simple in itself and can be clearly explained in one sentence . It means that the last step of a function is to call another function.
function g (x) {
console.log (x)
}
function f (x) {
return g (x)
}
console.log (f (1))
// In the above code, the last step of function f is to call function g, This is the tail call.
Copy the code In the above code, the last step of function f is to call function g, which is the tail call. The tail call does not necessarily appear at the end of the function, as long as it is the last operation.
The NC machine decryption function calls itself, called recursion. If the tail calls itself, it is called tail recursion. Recursion is very memory-intensive, because thousands of call frames need to be saved at the same time, and stack overflow errors are prone to occur. But for recursion at the end of the team, since there is only one call frame, a stack overflow error will never occur.
function factorial (n) {
if (n === 1) {
return 1
}
return n * factorial (n-1)
}
Copy the code The above code is a factorial function that calculates the factorial of n, at most need to save n call data, The complexity is O (n). If it is rewritten as a tail call, only one call record is kept, and the complexity is O (1).
function factor (n, total) {
if (n === 1) {
return total
}
return factor (n-1, n * total)
}
Copy code Fibonacci sequence can also be used for tail calls.
function Fibonacci (n) {
if (n <= 1) {
return 1
}
return Fibonacci (n-1) + Fibonacci (n-2)
}
// tail recursive
function Fibona (n, ac1 = 1, ac2 = 1) {
if (n <= 1) {
return ac2
}
return Fibona (n-1, ac2, ac1 + ac2)
}
Copy code
currying function In mathematics and computer science, currying is a function that converts a function that uses multiple parameters into a series that uses one parameter Function technology. The so-called currying is the process of converting a function with more parameters into a function with fewer parameters.
For example
// ordinary function
function fn (a, b, c, d, e) {
console.log (a, b, c, d, e)
}
// The generated
curry function let _fn = curry (fn )

_fn (1, 2, 3, 4, 5) // print: 1,2,3,4,5
_fn (1) (2) (3, 4, 5) // print: 1,2,3,4 , 5
_fn (1, 2) (3, 4) (5) // print: 1,2,3,4,5
_fn (1) (2) (3) (4) (5) // print: 1 , 2,3,4,5
Copy the code The realization of the
curried function // Do curry for the summation function
f1 = curry (add, 1, 2, 3)
console.log ('Complex version', f1 ()) // 6

// do curry
let f2 = curry (add, 1, 2) for the summation function
console.log ('complex version', f2 (3)) // 6

// Do curry
let for the summation function f3 = curry (add)
console.log ('complex version', f3 (1, 2, 3)) // 6

// The complex version of the curry function can be called multiple times, as follows:
console.log ('complex version', f3 (1) (2) (3)) // 6
console.log ('complex version', f3 (1, 2 ) (3)) // 6
console.log ('Complex version', f3 (1) (2, 3)) // 6

// Complex version (Each time you can pass in an indefinite number of parameters, and it will be executed when the total number of parameters passed is not less than the total number of formal parameters of the
function ) function curry (fn) {
// Closure
// The cache division function fn All parameters except
let args = Array.prototype.slice.call (arguments, 1)
return function () {
// connect the cached old parameters with the new incoming parameters (that is, put all the incoming parameters first Save it, but don't execute it)
let newArgs = args.concat (Array.from (arguments))
if (newArgs.length <fn.length) {
// The total number of parameters accumulated is less than the total number of fn parameters
// Recursively passed in fn and the accumulated parameters
return curry.call (this, fn,… newArgs)
} else {
// call
return fn.apply (this, newArgs)
}
}
}
Copy code usage of
currying Currying is actually to simplify The questions answered are complicated, but at the same time, we have more degrees of freedom when using functions. The free handling of function parameters here is at the core of currying. Currying is essentially reducing versatility and improving applicability. Let's look at an example:
In our work, we will encounter various requirements that need to pass the regular test, such as verifying the phone number, verifying the mailbox, verifying the ID number, verifying the password, etc. At this time, we will encapsulate a general function checkByRegExp, receiving two parameters , The regular object to be
checked and the string to be checked function checkByRegExp (regExp, string) {
return regExp.text (string)
}

checkByRegExp (/ ^ 1 \ d {10} KaTeX parse error: Undefined control sequence: \ w at position 46:… eckByRegExp (/ ^ (\ ̲w̲) + (\. \ w +) * @ (\ w)… /, ' [email protected] ') // To verify the mailbox
copy code, we need to enter a string of regulars every time we verify, and then verify the same type of data, we need to write the same regular multiple times, which leads to We are inefficient when using it, and since the checkByRegExp function itself is a tool function, it does not make any sense. At this time, we can use the currying to encapsulate the checkByRegExp function to simplify code writing and improve code readability.
// Perform currying
let _check = curry (checkByRegExp)
// Generate a tool function to verify the phone number
let checkCellPhone = _check (/ ^ 1 \ d {10} KaTeX parse error: Undefined control sequence: \ w at position 45:… il = _check (/ ^ (\ ̲w̲) + (\. \ w +) * @ (\ w)… /)

checkCellPhone ('18642838455') // Check phone number
checkCellPhone ('13109840560') // Check phone number
checkCellPhone ('13204061212') // Check phone number

In
the implementation of currying function parameter length function currying, fn.length is used to represent the number of function parameters. Does fn.length represent the number of all parameters of the function? Not really.
The length property of the function obtains the number of formal parameters, but the number of formal parameters does not include the number of remaining parameters, and only includes the number of parameters before the first one with a default value. See the following example.
((a, b, c) => {}). length
// 3

((a, b, c = 3) => {}).length
// 2

((a, b = 2, c) => {}).length
// 1

((a = 1, b, c) => {}).length
// 0

((…args) => {}).length
// 0

const fn = (… args) => {
console.log (args.length)
}
fn (1, 2, 3)
// 3
copy code compose function
compose is a combination function, the sub-functions are connected in series and executed, the output of a function The result is the input parameters of another function. Once the first function starts to execute, it will be deduced and executed like a domino.
const greeting = name => Hello ${name}
const toUpper = str => str.toUpperCase ()

toUpper (greeting ('Onion')) // HELLO ONION
copy code characteristics of compose function

compose accepts the function as a parameter, executes from right to left, and returns
all the parameters of the type function fn () to the function on the far right.

compose implementation
var compose = function (… args) {
var len = args.length // number of args functions
var count = len-1
var result
return function func (… args1) {
// args1 parameter enumeration of func function
result = args [count] .call (this, args1)
if (count> 0) {
count–
return func.call (null, result) // result The return result of the previous function
} else {
// Reply to the initial state
count = len-1
return result
}
}
}
Copy the code for an example
var greeting = (name) => Hello ${name}
var toUpper = str => str.toUpperCase ()
var fn = compose (toUpper, greeting)
console.log (fn ('jack '))
Copy the code The loader execution order in the CNC machine decryption that everyone is familiar with is from right to left, because webpack chooses the compose method, and the loader is executed in order from right to left, and each loader is a function.
rules: [
{test: /.css$/, use: ['style-loader', 'css-loader']}
]
Copy the code as above, webpack uses style-loader and css-loader, it uses css- The loader loads the .css file, and then style-loader injects the internal style into our html page.
The compose code in webpack is as follows:
const compose = (… fns) => {
return fns.reduce (
(prevFn, nextFn) => {
return value => nextFn (prevFn (value))
},
value => value
)
}

Published 28 original articles · Likes0 · Visits 907

Guess you like

Origin blog.csdn.net/srhgsr/article/details/105544512