14. Anonymous functions and closures

Source: Internet
Author: User

Anonymous functions and closures

Learning Essentials:
1. Anonymous functions
2. Closures


An anonymous function is a function that does not have a name, and a closure is a function that accesses a variable in a function scope. Disclaimer: The content of this section needs to be object-oriented and
A small number of design pattern bases.

First, anonymous function

Common functions
function box () {//Functions name is box
Return ' Lee ';
}

anonymous functions
function () {//anonymous functions, error, individual anonymous functions cannot be run
Return ' Lee ';
}

Self-executing with an expression
(function box () {//encapsulated as an expression
Alert (' Lee ');
});//() represents the execution function, and the parameter is passed. The first parenthesis puts an anonymous function, the second parenthesis executes

Assigning anonymous functions to variables
var box = function () {//Assign anonymous function to variable
Return ' Lee ';
};
Alert (Box ());//Call method is similar to function call

Assigning the return value of an anonymous function self-executing to a variable
var box = (function () {
Return ' Lee ';
})();
alert (box);//Where box is not added ()

Arguments for self-executing anonymous functions
(function (age) {
alert (age);
}) (100);

Anonymous functions in a function
function box () {///function anonymous functions, resulting in closures
return function () {
Return ' journey ';
}
}
Alert (Box ());//Call anonymous function, if not () print out the entire contents of the function, rather than execute

Second, closed package

Closures are functions that have access to variables in another function scope, and the common way to create closures is to create another function inside one function
, which accesses the local variables of the function through another function.

You can return a local variable by closing a packet
function box () {
var user = ' Lee ';
return function () {//Return box () local variable by anonymous function
return user;
};
}
Alert (Box ());//Call the anonymous function return value directly via box () ()

var b = box ();
Alert (b ());//Another call to anonymous function return value

The use of closures has one advantage, but also its disadvantage: it is possible to put local variables in memory, you can avoid the use of global variables. (Global Change
Pollution leads to unpredictable application, and each module can invoke disaster, so it is recommended to use private, encapsulated local variables.

To accumulate by global variables
var age = 100;//global variable
function box () {
The age++;//module level can call global variables to accumulate
}
box ();//execute function, accumulate
alert (age);//Output global variable

Accumulation cannot be achieved by local variables
function box () {
var age = 100;
Age ++;//Cumulative
return age;
}

Alert (Box ());//101
Alert (Box ()),//101, cannot be implemented because it is initialized again

Use anonymous functions to implement local variables residing in memory, thus accumulating
function box () {
var age = 100;
return function () {
age++;
return age;
};
}
var b = box;
Alert (b ());
Alert (b ());
Alert (b ());
Alert (b ());
b = null; Dereference is waiting for garbage collection to recycle

PS: Because the local variable returned by the scope in the closure is not destroyed immediately, it may consume more memory. Over-use closures
Resulting in performance degradation, it is recommended that closures be used when necessary.

The mechanism of the scope chain causes a problem in which any variable obtained by an anonymous function in the loop is the last value.

The function contains anonymous functions.
function box () {
var arr=[];
for (var i = 0; i<10; i++) {
Arr[i] = function () {
return i;
};
}
Loop has been executed, the most used because i<4 but also to + +, so the final I is 5
return arr;
}

var b = box ();//Get the function array, at this point the assignment to B is actually the above function completed 5
alert (b.length);//Get function set length
for (var i = 0; i<b.length;i++) {
Alert (B[i] ());//outputs the value of each function, which is the last value 5
}

The above example outputs a result of 5, which is the maximum I value obtained after the loop. Because B[i] calls an anonymous function, the anonymous function does not have a self
execution, wait until the call, box () has been executed, I has already become 5, so the final result is 5 5.

Change ()
function box () {
var arr = [];
for (var i = 0; i<5; i++) {
Arr[i]=i;
}
}
var b = box ();
for (var i = 0; i<b.length; i++) {
Alert (B[i]);
}

Change 1
function box () {
var arr = [];
for (var i = 0; i<5;i++) {
arr[i]= (num) {//Execute anonymous function in time by itself
return num;
}) (i);
}
return arr;
}
var b = box ();
for (var i = 0; i<b.length; i++) {
Alert (B[i]);
}

Change 2
function box () {
var arr = [];
for (var i = 0; i<5;i++) {
arr[i]= (function (num) {
Num is actually here
return function () {//Because closures can keep variables in memory, and the addition of the previous lesson is one reason
return num;
}
}) (i);
}

Already executed, num why can 0,1,2,3,4
return arr;
}
var b = box ();
for (var i = 0; i<b.length; i++) {
Alert (B[i] ());
}


function box () {
var arr = [];
for (var i = 0; i<5;i++) {
Arr[i]=function (num) {
Num is actually here
return function () {//Because closures can keep variables in memory, and the addition of the previous lesson is one reason
return num;
}
} (i);
}

Already executed, num why can 0,1,2,3,4
return arr;
}
var b = box ();
for (var i = 0; i<b.length; i++) {
Alert (B[i] ());
}

We self-execute through anonymous functions and immediately assign the result to A[i]. Each I, which is passed by the caller by value, is ultimately returned by referring to the
Constant increment of I. Instead of I in the box () function.


About this object
The use of this object in closures can also cause some problems when the This object is bound at run time based on the execution environment of the function, if this is in the global
The scope is window, if it is inside the object that points to the object. The closure, however, points to the window at run time, because closures do not belong to this
The properties or methods of an object.

var user = ' The Window ',
var obj = {
User: ' The Object ',
Getuserfunction:function () {
return function () {//closure does not belong to obj, this is a pointer to window
return this.user;
};
}
};
Alert (Box.getuserfunction () ());

Object Impersonation
Alert (Box.getuserfunction (). Call (box));

We can do that, too.
var user = ' The Window ',
var obj = {
User: ' The Object ',
Getuserfunction:function () {
Here the scope of this is box
return function () {
Here the scope of this is the window
return this.user;
};
}
};
We can assign the this in box to a variable var = this and return to That.user;
var user = ' The Window ',
var obj = {
User: ' The Object ',
Getuserfunction:function () {
Here the scope of this is box
var = this;
return function () {
Here the scope of this is the window
return that.user;
};
}
};
In this case, this is the Object in the closure.

About this object
var box = {
Getthis:function () {
return this;
}
};
alert (this);//object Window
Alert (Box.getthis ());//object Object

var box = {
Getthis:function () {
return function () {
return this;
}
}
};
Alert (Box.getthis () ());//object Window

Memory leaks
Because the JScript objects and Dom objects of IE use different garbage collection methods, closures can cause problems in IE. is a memory leak.
Problem, that is, the element that resides in memory cannot be destroyed. The following code has two knowledge points that have not been learned, one is DOM, the other is an event.

function box () {
var odiv = document.getElementById (' Odiv ');//odiv always resides in memory after it is exhausted
Odiv.onclick=function () {
alert (odiv.innerhtml);//The odiv here causes a memory leak
};
}
Box ();

Then the odiv should be dereferenced at the end to avoid a memory leak.
function box () {
var Odiv=document.getelementbyid (' Odiv ');
var text = odiv.innerhtml;
Odiv.onclick = function () {
alert (text);
};
Odiv = null;//dereference, waiting to be recycled
}

PS: If you do not use dereference, you need to wait until the browser is closed to release

Privatization
Impersonation block-level scope (private scope)
JavaScript does not have a block-level scope concept

function box (count) {
for (var i = 0; I <count; i++) {};
alert (i);
}
Box (2);

function box (count) {
for (var i = 0; i<count; i++) {}
var i;//does not affect the I value of the previously declared initialization, even if it is re-declared
alert (i);
}
Box (2);

The above two examples show that JavaScript does not have a scope for block-level statements, and if () {} for () {} is not scoped. If there is, out of this range:
Should have been destroyed. Even if you re-declare the same variable, it will not change its value.

JavaScript does not remind you that you have declared the same variable many times: In this case, it will only ignore the subsequent declaration (if the initialization
, and of course it will be executed). Using the impersonation block-level scope avoids this problem.

Impersonation block-level scope (private scope)
(function () {
This is a block level scope.
})();

Overwrite with block-level scope (private scope)
function box (count) {
(function () {
for (var i = 0; i<count; i++) {}
})();
alert (i);//error, unable to access
}

When a block-level scope (private scope) is used, any variables defined in the anonymous function are destroyed at the end of execution, which is often
The global scope is used outside the function to limit the addition of too many variables and functions to the global scope. Generally speaking, we should all try to
Add variables and functions to the global scope less. In large projects, when multi-person development, too many global variables and functions can easily lead to the naming of punch
Cause catastrophic consequences. If you take a block-level scope (private scope), each developer can use his or her own variables without worrying about
Clutter the global scope.

(function () {
var box = [1,2,3,4];
alert (box);//box come out, I don't know.
})();

Global variables

var age = 100;
alert (age);

After the global variables have been exhausted, you must use NULL to clear the wait for recycling, and use private scopes that are not needed because they are automatically destroyed, which is a good limit
Use of variables

Private scopes to represent

(function () {
var age = 100;
alert (age);
})();

Using a block-level scope in a global scope reduces the memory problems that are used by closures because there is no reference to the anonymous function. As long as the function executes
Complete, you can immediately destroy its scope chain.

Private variables
JavaScript does not have the concept of private properties; All object properties are public. However, there is a concept of a private variable. Any in the function
Variables that are defined can be considered private variables because they cannot be accessed outside of the function.
function box () {
var age = 100;//Private variable, external unreachable
}

By creating a closure within the function, the closures can also access these variables through their own scope chain. With this, you can create a
Public methods to access the private variables.

function Box () {
This.age = 100;//Property, public
This.run = function () {//method, public
Return ' running ... ';
};
}
var box = new box ();
alert (box.age);

Private can't use this.
function Box () {
var age = 100;//Private variable
function run () {//Private functions
Return ' running ... ';
}
This.get = function () {//External public privileged method
return Age+run ();
};
}
var box = new box ();
Alert (Box.get ());

You can also access a private variable by constructing a method pass parameter.
function person (value) {
var user = value;
This.getuser = function () {
return user;
};
This.setuser = function (value) {
user = value;
};
}
var person= new person (' journey ');
Alert (Person.getuser ());

However, the method of the object, which is created multiple times at multiple calls, can be used to avoid this problem by using static private variables.

Static private variables

Private variables and functions are defined through block-level scopes (private scopes), and you can create privileged methods that are external to the public.

(function () {
var user = ';
person = function (value) {
user = value;
};
Person.prototype.getuser=function () {
return user;
};
Person.prototype.setuser=function () {
user = value;
}
})();
var person =new person (' journey ');
Alert (Person.getuser ());

The use of prototype causes the method to be shared, and the user changes the static properties. (So-called static properties, which are properties shared in different objects
)。

Module mode
Previously, the constructor was used to create private variables and privileged methods. Then the object literal is created using module mode.
What is a single example: is always only instantiated once, in fact, is the literal object declaration way
var box = {//literal object, also singleton object, cannot be instantiated for the second time
age:100;//This is a public property and will be changed to private
Run:function () {//This is a public function and will be changed to private
Return ' running ... ';
};
};

Privatization variables and functions:
var box = function () {
var age = 100;
function Fun () {
Return ' running ... ';
}
return{//returning objects directly
Go:function () {
return Age+fun ();
}
};
}();

The above example of a direct return object can also be written like this:
var box = function () {
var age = 100;
function Run () {
Return ' running ... ';
}
var obj = {
Go:function () {
Return age + run ();
}
};
return obj;
}();

The literal object declaration, in fact, can be regarded as a singleton pattern in design pattern, so-called singleton mode, which is an instance of Forever saving object.
Enhanced module mode, which is suitable for returning custom objects, that is, constructors.
function Desk () {};
var box = function () {
var age = 100;
function Run () {
Return ' running ... ';
}
var desk = new Desk ();//Can instantiate a specific object
Desk.go = function () {
Return age + run ();
};
return desk;
}();
Alert (Box.go ());

14. Anonymous functions and closures

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.