navigation

[Deep 01] Execution context [Deep 02] Prototype chain [Deep 03] Inheritance [Deep 04] Event loop [Deep 05] Curri Bias function [Deep 06] Function memory [Deep 07] Implicit conversions and operators [Deep 07] Browser caching mechanism (HTTP caching mechanism) [Deep 08] Front-end security [Deep 09] Deep copy [Deep 10] Debounce Throttle [Deep 10] Front-end routing [Deep 12] Front-end modularization [Deep 13] Observer mode Publish subscribe mode Bidirectional data binding [Deep 14] Canvas [Deep 15] webSocket Webpack HTTP and HTTPS CSS- Interview Handwriting Promise

[react] Hooks

[Deployment 01] Nginx [Deployment 02] Docker deployVue project [Deployment 03] gitlab-CI

[source code – Webpack01 – precompiler] AST abstract syntax tree [source code – Webpack02 – Precompiler] Tapable [source code – Webpack03] hand written webpack-compiler simple compilation process [source code] Redux React-redux01 [source] Axios [source] vuex [source -vue01] data Reactive and initial render

Front knowledge

Parameter of a function

  • Length: The function’s legth attribute, which returns the number of parameters (parameters) the function expects to take.
  • Arguments: The Arguments object that contains all the arguments (arguments) that the program runs with

Converts an array-like object to an array

  • [].slice.call(array like object)
  • [].slice. Apply (array-like object)
  • Array. The prototype. Slice. Call (similar to an Array of objects, x)// x is the parameter passed to the slice function after binding this
  • Array.from()

Partial functions and the concept of Curryization

  • 2. Curry:
    • Convert a function that takes multiple arguments to a function that takes a single argument and returns a new function that takes the remaining arguments and returns the final result
    • If the parameters are smaller than the expected parameters, return a function that can receive the rest of the parameters. If the parameters are greater than or equal to the expected parameters, return the final result
  • Partial application:
    • Is a function that fixed one or more parameters, producing another smaller element n element function => convert to n-x element function

Currie curry

  • A curryized function that takes A as an argument and runs to return A new function that handles the rest of A’s arguments

1. Phase 1 of Currying

  • Requirements:Convert add(1,2,3) to curryAdd(1)(2)(3)
  • Disadvantages: Can only handle the case of 3 parameters, can not handle any number of parameters, no extensibility
Convert add(1,2,3) to curryAdd(1)(2)(3) Can only handle the case of 3 parameters, can not handle the case of any number of parameters, Function curryAdd(a) {return function(c) {return a+b+c}}} const res = curryAdd(1)(2)(3) console.log(res, 'res1')Copy the code

2. Stage 2 of Currying

  • Requirements:Handles the addition of any number of parameters
  • Disadvantages:
    • 1. The code that handles adding logic will only be executed when there are no parameters. Other parts are dealing with how to collect all parameters, so there will be one more call without parameters
      • A more reasonable way to determine whether the parameter collection is complete is to determine that the function can receive the sum of the parameters
    • 2. Additive logic can be detached separately
Function closure() {const args =. Function closure() {const args =. Function closure() {const args = Array. The prototype. Slice. The call (the arguments) / / every time the argument of the incoming call closure function If (args.length) {params_arr = params_arr.concat(args)} return closure // Closure if (args.length) {params_arr = params_arr.concat(args)} return closure if (args.length) {params_arr = params_arr.concat(args)} } return params_arr.reduce((total, current) => total + current)} return params_arr.reduce((total, current) => total + current)} return params_arr.reduce((total, current) => total + current) } return closure // const fn = curryAdd() const res = fn(1,2)(3)(4)()} closure () const fn = curryAdd() const res = fn(1,2)(3)(4)() console.log(res, 'res'); / / 10Copy the code

3. Stage 3 of Currying

function add(a,b,c,d,e) { return Array.prototype.slice.call(arguments).reduce((total, Current) => total + current) So what we get here is the actual number of arguments, which means that the argument may be greater than the parameter, and when the argument is greater than or equal to the parameter, } function curryAdd(fn) {let paramsArr = [] const paramsMaxLength = fn.length // function.length returns the number of parameters to the function, The expected number of parameters is the maximum number of parameters, As additive performs conditional function closure () {const args = Array. The prototype. Slice. The call (the arguments) paramsArr = paramsArr. Concat (args) the if (paramsarr. length < paramsMaxLength) {return closure} (paramsarr. length < paramsMaxLength) {return closure} Return fn. Apply (this, ParamsArr)} return closure} const fn = curryAdd(add) const res = fn(1,2,3)(4)(5,6) console.log(res, 'res');Copy the code

4. Currie adaptation

  • Disadvantages of the above version: The above version needs to know the length of the add parameter
function add() { return Array.from(arguments).reduce((total, Current) => total + current)} function currentAdd(fn) {let function closure() {let paramsArr = [] function closure() { GetSum const args = array. from(arguments) paramsArr = paramsarr. concat(args) return closure} Closure. GetSum = function() {return fn. Apply (this, paramsArr); ParamsArr} return closure} const fn = currentAdd(add) const resAdd = fn(1)(2,3) const res = resadd.getsum (); // The disadvantage of this method is that you need to call the getSum function console.log(res, 'res') separately.Copy the code

Partial function partial

  • Fixes one or more arguments to a function and produces a function that returns a smaller element
function add (a, b) { return a + b } function partial (fn) {... } const addPartial = partial(add, 1) / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- a part of the fixed parameter 1 const res = addPartial (2) / / 3 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - only 2 part parametersCopy the code

Partial function implementation method 1

  • The bind method is used
  • The bind method binds to this, can also pass some or all of fn's arguments, and returns a new function that can pass arguments as the rest of fn's arguments
function add(a,b,c,d) { return a+b+c+d } function partail() { const params = Array.prototype.slice.call(arguments) const Fn = params.shift() return fn. Bind (this,... Params) // The params array has changed after shift // all the members after the params array has been expanded, } const fn = partail(add, 1, 2) const res = fn(3,4) The rest of the arguments are passed here console.log(res, 'res')Copy the code

Partial function implementation 2

function add(a,b,c,d) { return Array.from(arguments).reduce((total, } function partialAdd(fn) {let paramsFixed = paramsFixed Array. From (arguments).slice(1) This method is similar to curry. The first call to current does not need to pass fn, and declares an empty array. Function closure() {const args = Array. From (arguments) closure() {const args = Array. From (arguments) paramsFixed = paramsFixed.concat(args) if (paramsFixed.length < paramsMaxLength) { return closure } return } return closure} const fn = partialAdd(add, paramsFixed) 2) const res = fn(3)(4)(5) console.log(res, 'res') // 14Copy the code

Memory function

  • Functional memory:To cache the data from the last call and return the same data on the next call.
  • Implementation principle: the parameters and corresponding results are saved in the object, and when called again, the key of the object is judged whether there is a value returned to the cache
    • Note: Functions need to return a value
function memorize(fn) {
  const cache = {}
  return function() {
    const key = Array.prototype.join.call(arguments, ',')
    if (key in cache) {
      return cache[key]
    }
    return cache[key] = fn.apply(this, arguments)
  }
}
Copy the code

I’m Jane books: www.jianshu.com/p/eb583d764…

The tail call

Tail call: The last step in a function's execution, which is to return another function call. < span style = "box-size: border-box; margin-top: 0px; margin-bottom: 0px; F (x) {return g(x) + 1} f(x) {return g(x) + 1} Const a = x => x? Const a = x => x? Const a = x => x? Const a = x => x? f() : g(); / / f () and g () is the tail call const a = = > f () () | | g / / f () () the end the call, and then judge const a = = > f () () () && g; // f() is a non-tail callCopy the code

Tail recursion

Recursion - tail recursion and tail call 1. Form the condition of recursion - boundary condition - Recursive forward segment - Recursive return segment - Recursion forward when boundary condition is not satisfied - recursion returns when boundary condition is satisfied 2. Tail call and non-tail call - The difference between tail call and non-tail call is that the execution context stack is different - for the call: (g(x)) (f(x)) (g(x)) (f(x)) (g(x)) (f(x)) Function f(x){return g(x); } function f(x){return g(x)+1; function f(x){return g(x)+1; } -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + + (1) factorial / / recursive recursive function  factorial (n) { if (n < 2) return n return n * factorial(n-1) } const res = factorial(3) // 1. 3 => 3 * factorial(2) => 3 * 2 * factorial(1) => 3 * 2 * 1. Each time a recursive function is returned, a closure is created. 2. Therefore, maintaining so many execution context stacks is expensive and can cause memory leaks. Optimization method: Function factorial(n, res) {if (n === 1) {return res} return factorial(n-1, n * res)} (analysis) First: Factorial (3, 4* 1) Second time: factorial (2, 3* 4) Third time: factorial (1, 2* 12) Fourth time: Function factorial(res, n) {if (n === 1) return res; return factorial(n * res, n-1) } function curring (fn) { let par_arr = Array.prototype.slice.call(arguments, 1) const closure = function () { par_arr = par_arr.concat(Array.prototype.slice.call(arguments)) console.log(par_arr, 'par_arr') if (par_arr.length < fn.length) { return closure } return fn.apply(null, par_arr) } return closure } const curringFactorial = curring(factorial, 1) const res = curringFactorial(4) console.log(res)Copy the code