A, closures

1.1- How to access local variables outside a function

Each function in JS has its own scope. Variables defined in the current function can only be accessed within that function or within its nested functions. Such as:

function fun(){ var a = 123; console.log(a); //123 } console.log(a); // Error: a is undefinedCopy the code

In development, if you need to access a function’s local variables outside the current function scope, can you do that? Look at the following code:

function fun() { var a = 123; function fun2() { return a; } return fun2; } var fun3 = fun(); console.log(fun3()); / / 123Copy the code

Another function,fun2, is defined in function fun. Fun2 accesses the local variable a outside the function and returns fun2.

Calling fun returns the value (the fun2 function), and since the return value is a function, we call the value of a returned from the function.

Definition: a function that has access to variables in the scope of another function.

Effect: break the scope of the function, the current function outside the scope of access to the internal private members of the function, prolong the declaration period of variables.

Features:

  1. Make it possible for external access to function internal variables;
  2. Local variables live in memory;
  3. Can avoid using global variables, prevent global variable pollution;
  4. Memory leaks (where a piece of memory is occupied for a long time and is not released)

1.2- Closures access and set data

If you need to access multiple private members of a function, how can you do that? You can use arrays or objects.

  1. Return Function > Return Array > Private Member

    function fun() { var a = 123; var b = 456; return function() { return [a, b]; } } var f = fun(); var a = f()[0]; var b = f()[1]; console.log(a, b); / / 123 456Copy the code
  2. Return Array > Function > Return Private member

    function fun() { var a = 123; var b = 456; return [ function() { return a; }, function() { return b; } ]; } var f = fun(); var a = f[0](); var b = f[1](); console.log(a, b); / / 123 456Copy the code
  3. Return Object > Function > Return private member

    // Both of the above methods use an array to access multiple private members, which is difficult to implement in practice, because the array uses all the elements to access, if the array has a large number of elements, then this method is prone to error. So we thought of returning in the form of an object. function fun() { var a = 123; var b = 456; return { getA:function () { return a; }, getB:function () { return b; }}; } var f = fun(); var a = f.getA(); var b = f.getB(); console.log(a, b);Copy the code
  4. Function + returns an object

    Function fun() {var a = 123; function fun() {var a = 123; var b = 456; function getA() { return a; } function getB () { return b; } return { getA:getA, getB:getB }; } var f = fun(); var a = f.getA(); var b = f.getB(); console.log(a, b);Copy the code
  5. Modular development (with immediate execute functions)

    // If you need to use modular development, you can do a package of the above code, with immediate execution of the function. var modual = (function () { var a = 123; var b = 456; function getA() { return a; } function getB() { return b; } function setA(value) { a = value; } function setB(value) { b = value; } return { getA:getA, getB:getB, setA:setA, setB:setB }; }) (); // Execute the function immediately, returning the internal encapsulated object modual. SetA (100); modual.setB(200); var a = modual.getA(); var b = modual.getB(); console.log(a, b); / / 100 200Copy the code

1.3- Timer time and closure execution

Requirements: use setTimeout to start 10 timers, output 0,1,2,3,4,5,6,7,8,9.

If it’s as simple as this, let’s use the for loop:

for (var i = 0; i <10; i++) {
    setTimeout(function(){
        console.log(i);
    }, 1000);
}
Copy the code

The for loop will complete in a flash, and the timer is asynchronous, so it’s already all 10.

Sorry, the output is 10 tens instead of the consecutive numbers we need.

Method 1: Execute the function immediately

So the solution is actually out, because the function in the timer did not execute immediately caused the problem, so let it execute immediately OK!

for (var i = 0; i <10; i++) { setTimeout( (function(){ console.log(i); })(), // execute function 1000 immediately); }// wrong !!!!!!!!! for (var i = 0; i < 10; i++) { (function (i) { setTimeout(() => { console.log(i); }, 1000) })(i) }Copy the code

The first argument to setTimeout requires a function, which is indeed an undefined pass.

Method two: closures

for (var i = 0; i < 10; i++) { function fun(){ return function (j) { console.log(j); } // If the setTimeout function requires arguments // the arguments are after the second argument (time) of setTimeout. setTimeout(fun(),1000,i); }Copy the code

1.4-DOM events and closure execution

Extends the lifetime of the event return value

The ul id = "test" > < li > this is the first article < / li > < li > this is the second article < / li > < li > this is the third article < / li > < / ul > < script > var liList=document.getElementsByTagName('li'); For (var I = 0; i < liList.length; I++) {(function fun (j) {liList [j]. Journal of onclick = function () {the console. The log (' first '+ (j + 1) +' li '); } // closure for (var I = 0; i < div.length; I++) {div [I] onclick = (function (j) {return function () {the console. The log (' first '+ (j + 1) +' div '); } })(i) } </script>Copy the code

Ii. Brief description of design patterns (Understanding)

2.1- Singleton mode

Definition: A class is guaranteed to have only one instance and a global point of access to it.

Core: Ensures only one instance and provides global access.

Implementation: Assuming that we want to set an administrator, and that multiple calls are set only once, we can implement this singleton by caching an internal variable. Implementation: Assuming that we want to set an administrator, and that multiple calls are set only once, we can implement this singleton by caching an internal variable.

var _instance; Function Person() {if(_instance){console.log(' previously created, directly return the previously created object '); return _instance; } _instance = this; Console. log(" created object "); } var p1 = new Person(); var p2 = new Person(); console.log(p1 === p2); // true, they are the same objectCopy the code

2.2- Observer Pattern

Definition: defines a one-to-many dependency relationship between objects so that all dependent objects are notified when an object’s state changes.

For example:

  1. Sales department’s customer service sister – there is a new house – the observed Subject
  2. Direct notification to various potential customers – observers
  3. Different customers react differently

Drawing description:

// Subject, receiving state change, Class Subject {constructor() {this.state = 0 this.observers = []} getState() {return SetState (state) {this.state = state this.NotifyAllobServers ()} }} // After the state update, NotifyAllObservers () {this.obsers.foreach (observer => {observer.update()})}} // Observers, Class Observer {constructor(name, constructor) {this.name = name this.subject = subject this.subject.attach(this)} Update () {console.log(' ${this.name} update, state: ${this.subject.getstate ()} ')}} let s = new subject () let o1 = new Observer('o1', S) let o2 = new Observer('o2', s) let o3 = new Observer('o3', s) S.setstate (1) S.setState (2) S.setState (3)Copy the code

2.3 Publish – Subscribe Pattern

Definition: Similar to the observer mode, only with a dispatch center in the middle.

For example:

  1. Sales department customer service sister – there are new housing – Publish
  2. Little Sister publishes the new housing information to an official platform (dispatch center)
  3. Users who need to buy a house (subscribe) see the information on the official account
  4. Different customers react differently

Drawing description:

Confusion: Many sources confuse the observer pattern with the publish/subscribe pattern because there are two roles implementing a one-to-many relationship (observer – observer, publisher – subscriber). Indeed, confusion can occur, and they ignore the broker role or scheduling center in the publish/subscribe model.