Talk about closure scenarios

I gave you a brief introduction to closures and what they do. In this installment, we’ll talk about the application scenarios of closures.

Implementation of singletons

A singleton is a class that provides a way to access its unique objects globally. Note that the key word is that this object is unique, which means that calling the singleton creation method returns the same object.

function Person() { this.name = 'ouda' } Person.sharedInstance = (function () { var instance; return function () { if (! instance) { instance = new Person() } return instance; } })() const p1 = Person.sharedInstance() const p2 = Person.sharedInstance() console.log(p1 === p2)Copy the code

Both p1 and P2 are created using sharedInstance(). They access the same internal variable instance, forming a closure, so p1 and P2 refer to the same object. So as long as the object created by this method is the same and unique, this is how closures are used to create singletons.

2. Privatization of attributes

When we want to protect a variable from direct external access, we can use closures to privatize the variable.

Suppose you have 3 lives in a game, and when you reach the condition, you have +1 health, and when you trigger another scenario, you have -1 health. In order to protect the health variable, it can only be +1 or -1 by the rule, and cannot be modified by other functions or accessed in other scopes, we can do this:

function Role() {
  var life = 3

  this.addLife = function () {
    life++
    return life
  }

  this.minLife = function () {
    life--
    return life
  }

  this.getLife = function () {
    return life
  }
}

const role = new Role()
console.log(role.addLife()) // 4
console.log(role.addLife()) // 5
console.log(role.minLife()) // 4
role.life = role.life + 100
console.log(role.getLife()) // 4
Copy the code

It can be found that the life variable under Role can only be changed by addLife and minLife, and the rules of change are stipulated within the function. You can’t access this variable directly through role-.life, let alone try to change its value.

3. Corrification of functions

What is corrification?

Currying is a technique that converts 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 a result.

If you want to implement a numeric accumulator (1+2+3+4….)

Primary writing:

function sum(a, b) {
  return a + b
}

let res = sum(1, 2)
res = sum(res, 3)
res = sum(res, 4)
console.log(res) // 10
Copy the code

Write the sum function as many times as you need to add it.

Intermediate writing:

function sum() {
  const numbers = Array.from(arguments)
  return numbers.reduce((a, b) => { return a + b })
}
console.log(sum(1, 2, 3, 4, 5, 6)) //21
Copy the code

The number of arguments is cleverly unlimited by using function arguments.

High level writing of corrification:

function sum() {
  var numberList = Array.from(arguments)
  var _sum = function () {
    numberList = numberList.concat(Array.from(arguments))
    return _sum
  }
  _sum.valueOf = function () {
    return numberList.reduce((a, b) => { return a + b })
  }
  _sum.toString = function () {
    return numberList.reduce((a, b) => { return a + b })
  }
  return _sum
}

const res = +sum(1, 2, 3)(4)(5, 6)
console.log(res)
Copy the code

Calls are more arbitrary, you can have unlimited arguments, and you can chain calls, and functions are codized using closures. NumberList is a private variable in a closure.