Higher-order functions

The function is a first-class citizen

A function can be used as an argument to another function or as a return value of another function

A function that takes another function as an argument or returns a function as a value is called a higher-order function

// Accept functions as arguments
function calc(num1, num2, fn) {
  if (Object.prototype.toString.call(fn) === '[object Function]') {
    return fn(num1, num2)
  }

  console.error('fn is not a function')}console.log(calc(10.20.(num1, num2) = > num1 + num2)) / / = > 30
console.log(calc(10.20.(num1, num2) = > num1 - num2)) / / = > - 10
console.log(calc(10.20.(num1, num2) = > num1 * num2)) / / = > 200
Copy the code
// function as the return value of the function
function add(count) {
  return num= > num + count
}

console.log(add(5) (10)) / / = > 15
console.log(add(10) (10)) / / = > 20
Copy the code

A higher-order function of an array

Filter: Specifies the filter function

  1. The parameter is aThe callback functionThe array has several elements, and the callback is executed several times. That is, the callback is passed in for each element of the array
  2. This callback needs to return a Boolean value, which, if true, will add the current array element to the new array
  3. This callback takes three arguments(item, index, arr), respectively,(Current element, current index, current array)
// Take all the even numbers in the array and form a new array
console.log([23.44.67.22.35.64.33].filter(v= > v % 2= = =0))
Copy the code

Map - A mapping function

  1. The parameter is aThe callback functionThe array has several elements, and the callback is executed several times. That is, the callback is passed in for each element of the array
  2. This callback takes three arguments(item, index, arr), respectively,(Current element, current index, current array)
  3. The return value of callback is added to the new array
// Each item in the array is doubled
console.log([23.44.67.22.35.64.33].map(item= > item * 2))
Copy the code

ForEach -- traversal functions

  1. The parameter is aThe callback functionThe array has several elements, and the callback is executed several times. That is, the callback is passed in for each element of the array
  2. This callback takes three arguments(item, index, arr), respectively,(Current element, current index, current array)
// Iterate over each entry in the print array
[23.44.67.22.35.64.33].forEach(item= > console.log(item))
Copy the code

Find/findIndex -- Find function

  1. The argument is a callback function that returns a Boolean that terminates the find/findIndex function when it returns true

    • findThis function will call the current callbackitemReturn as the return value
    • findIndexThis function will call the current callbackindexReturn as the return value
  2. This callback takes three arguments (item, index, arR) : (Current element, current index, current array)

  3. Find /findIndex can only find the first value that meets the condition, but cannot find all values that meet the condition

const arr = [23.44.67.22.35.64.33]

console.log(arr.find(item= > item % 2= = =0)) / / = > 44
console.log(arr.findIndex(item= > item % 2= = =0)) / / = > 1
Copy the code

Reduce - accumulation function

The reduce function takes two arguments

  • Parameter 1 is the callback function
    • The callback function takes two arguments: the previous value (prevValue) and the current value (currentItem)
    • The return value of the current callback is used as the prevValue value of the next callback
    • If it is the last callback, the return value of that callback is returned directly as the final return value
  • Parameter 2 is the initial inital value
    • If no initial value is set, the default initial value is 0
    • The initial value will be the prevValue of the first callback
/ / sum
console.log([23.44.67.22.35.64.33].reduce((prev, item) = > prev + item, 0))
Copy the code

closure

A normal function is a closure if it has access to free variables in the outer scope

If a variable "a" is used in a scope and is not declared in that scope (it is declared in other scopes), it is a free variable

Closures are not unique to JS. They exist in any language where functions are first-class citizens

In a broad sense: Functions in JavaScript are closures

In a broad sense, a function can constitute a closure as long as it has access to free variables
// Foo is also a closure function
function foo() {}
Copy the code

In a narrow sense: a function in JavaScript is a closure if it accesses a variable on which the outer layer operates

let name = 'coderwxf'

function printName() {
  // printName is a function
  PrintName accesses the free variable name of the outer scope
  // printName will be a closure
  console.log(name)
}
Copy the code

Memory analysis

function foo() {
  var name = "foo"
  var age = 18

  function bar() {
    console.log(name)
    console.log(age)
  }
  return bar
}

var fn = foo()
fn()
Copy the code

When var fn = foo() is executed on line 12, it looks like this:

At this point, in global GO, there is an attribute fn that points to the function object corresponding to bar, and foo’s AO object exists in the [[scope]] property of bar

So foo’s AO object is also referenced, so even though bar and foo’s execution context are now off the stack,

However, the function object of bar and the AO object of foo are not removed by GC because they still have references, so fn can be called on line 13

Remove the closure

function foo() {
  var name = "foo"
  var age = 18

  function bar() {
    console.log(name)
    console.log(age)
  }
  return bar
}

var fn = foo()
fn()

fn = null
Copy the code

If there is no need to execute the fn function after fn() on line 13, in principle the fn function should be removed by GC

But because the FN property exists on GO and is referenced by GO, and GO exists throughout the code execution cycle, the closure is always there and cannot be destroyed automatically by GC

However, memory capacity is limited, and too many closures that are no longer used can reduce the actual available memory space, which is called a memory leak

So for closures, we need to clean them up manually by doing line 15 and setting the reference to the closure to NULL

Null is a special block of memory address defined in JS. When the corresponding attribute in GO is set to NULL, it means that the FN attribute of GO points to the corresponding block of memory address

No longer pointing to the corresponding function object of bar, the GC will automatically reclaim the corresponding function object of bar and the corresponding AO object of foo when appropriate.

To remove closures that we don’t need anymore