JavaScript Ninja Cheats Chapter fifth notes (closures)

Source: Internet
Author: User
Tags closure wrapper
What is closure:

is a scope created by a function when it is created to allow its own function to access and manipulate variables other than that of its own function

Closures enable functions to access all variables and functions of the scope when the function is declared

The example in the book I see is inexplicable .... Even take it for granted that ....

Let's just write it.

  var outvalue= ' ninja ';
  var later;
  function Outfunction () {
      var innervalue= ' Samurai '
      function innerfunction (paramvalue) {
          Console.log ( Outvalue)//global scope of certainty can get
          console.log (innervalue)//Because the closure of the formation of the innerfunction function is always exist will protect the scope will not be garbage collection
          Console.log (paramvalue)//Incoming parameter is also able to
          Console.log (toolate)//In the calling method is Toolate has been declared
      }
      later= innerfunction;//this forms a closure.
  }
  Console.log (toolate)
    var toolate= ' Hello '
    outfunction ();
  Later (' Wakizashi ')
using closures

At least on the top we know, the use of closures, now see what the specific purpose of using closures to simulate private variables

    function Ninja () {
        var feinit=0;
        This.getfrinit=function () {return
            feinit;
        }
        This.feinits=function () {
            feinit++;
        }
    }
    var ninja=new ninja ();
    Ninja.feinits ();
    Console.log (Ninja.getfrinit ())//1

In fact, this usage, in ES6 already has an alternative, where ninja in the Feinit variable if you do not pass the method you are unable to modify its callback and timer

Basically it's not to mention that most anonymous functions appear in callbacks .... Binding Function Context

Let's take a look at an example:

    var button={
        Clicked:false,
        click:function () {
            this.clicked=true;
            Console.log (button.clicked);
        }
var Elem=document.getelementbyid ("Test");
    Elem.addeventlistener ("click", Button.click,false);

Would you know if the clicked in the button would be true and he would be false?

Why is that?

Because in the example, the event handling system of the browser thinks that the context of the function call is the target element of the event

Which is the DOM element, not the button function.

So the assignment didn't work.

Continue to modify this example you're not mistaken or apply

    function bind (context, name) {return
        function () {return
            context[name].apply (context,arguments);
        }
    }
    var button={
        clicked:false,
        click:function () {
            this.clicked=true;
            Console.log (button.clicked);
        }
var Elem=document.getelementbyid ("Test");
    Elem.addeventlistener ("Click", Bind (Button, "click"), False);

And here the closure is passed to the button function overload with the parameters of bind

Cache Memory:

There are two ways to implement it, the first to modify an existing function, or to create a new function that is updated based on an existing function. To modify an existing function to add a property memory field

Function.prototype.memoized=function (key) {
    this._value=this._value| | {};
    Return this._value[key]!==undefined?
    This._value[key]:
        this._value[key]=this.apply (this,arguments);

function IsPrime (num) {
    var prime=num!=1;
    for (Var i=2;i<num;i++) {
        if (num%i==0) {
            prime=false;
            break;
        }
    }
    return prime;
}
Console.log (isprime.memoized (5))
Console.log (isprime._value[5))

In fact, this is the same as the self-memory function I wrote before, and if you don't know how to write this, look at the previous

JavaScript Ninja cheats Fourth Chapter notes (function Advanced) The second use closure implementation

Function.prototype.memoized=function (key) {
    this._value=this._value| | {};
    Return this._value[key]!==undefined?
    This._value[key]:
        this._value[key]=this.apply (this,arguments);
Function.prototype.memoize=function (key) {
    var fn=this;
    return function () {return
        fn.memoized.apply (fn,arguments);
    }
}
var isprime= (function (num) {
    var prime=num!=1;
    for (Var i=2;i<num;i++) {
        if (num%i==0) {
            prime=false;
            Break;}}}
). Memoize ();
Console.log (IsPrime (5))

You can see the omission of a step, you can see the code call IsPrime (), it is called memoize, followed by the value of the closure of the logic

But it's a little bit complicated to write, the back optimization function Encapsulation

Function wrapping is a technique for encapsulating function logic to overload the creation of new or inherited functions within a single step. The most valuable scenario is when you overload some existing functions while maintaining that the original function can still be used effectively after being packaged.

function Wrap (object,method,wrapper) {
    var fn = Object[method];

    return Object[method] = function () {return
        wrapper.apply, This,[fn.bind (This)].concat (
            Array.prototype.slice.call (arguments)));}

if (Prototype.Browser.Opera) {
    wrap (element.methods, "Readattribute", function (original,elem,attr) {
        return attr = = "title"? Elem.title:original (elem,attr);}

The above code first saves the original method in the variable FN, and later we will access it via the closure of the anonymous function. We then use a new anonymous function to overload the method. The new function executes the wrapper function wrapper that was passed in before and passes a reconstructed argument list. When we build this argument list, we want the first argument to be the original function we want to overload, so we create an array that contains a reference to the original function and appends the original parameter to the array. Instant function (immediate function)

(function () {}) ();

We use it often when we're writing frames, so let's dissect this code.

The first bracket (...) is ignored. ();

We know that () more is used to call the function, the first () is what to do, is used to delimit the scope of the expression
such as (3+4) *5 this () is to delimit the expression orientation

And in the first bracket, you can write a function, or an anonymous function like

(function () {}) ();

And the back bracket executes the function, and the inside is destroyed.

Let's take a look at the temporary scope and private variables of the immediate function:

    (function () {
        var numclick=0;
        Document.addeventlistener ("click", Function () {
            alert (++numclick);
        },false)
    }) ()

You can see that the Numclick property only has access to the property in the closure, while the function runs the click event to be bound and externally inaccessible

This is also one of the most common forms of instant function usage: simple, self-wrapping solves the problem of cyclic variables

<body>
    <div style= "width:500px;height:500px;background-color:red" ></div>
    <div Style = "Width:500px;height:500px;background-color:green" ></div>
    <div style= "width:500px;height:500px; Background-color:black "></div>
</body>
<script type=" Text/javascript ">
    var divs =document.getelementsbytagname ("div");
        for (Var i=0;i<divs.length;i++) {
            divs[i].addeventlistener (' click ', Function () {
                alert ("DIVs" +i+ "was Click ")

            },false)
            }
</script>

Here cause I'll always be the last one, what's this for?

The closure remembers the reference to the variable, not the value of the variable at the time the closure was created.

How to solve it. Use immediate function

    var divs=document.getelementsbytagname ("div");
    for (var i=0;i<divs.length;i++) (function (n) {
         divs[n].addeventlistener ("click", Function () {
                alert ("DIVs "+n+" was click ")

            },false)
    }) (i)
Class Library Encapsulation

Another important use of the closure and instant function fine-grained applications is for the development of JavaScript class libraries, when we develop a class library, it is important not to want some unnecessary variables to pollute the global namespace, especially those temporary variables

such as: jquery

(function () {
    var jquery=window.jquery=function () {
        ...
    };
    //...
}) ()

To ensure that sometimes the jquery object in the window is also destroyed, a variable is also given in the closure

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.