JavaScript anonymous functions and closures)

Source: Internet
Author: User
Tags define function

Content
Introduction
Anonymous Functions
Closure
Variable Scope
External function access to local variables in a function
Use closures to implement Private Members
Introduction
Closures are implemented using anonymous functions. A closure is a protected variable space generated by embedded functions. The idea of "Variable Protection" can be seen in almost all programming languages.
Let's take a look at the JavaScript scope:
JavaScript has a function-level scope. This means that variables defined in the function cannot be accessed outside the function.
The JavaScript scope is lexical (lexically scoped ). This means that the function runs in the scope that defines it, rather than in the scope that calls it. This is a major feature of JavaScript, which will be described later.
By combining these two factors, we can wrap variables in anonymous functions to protect them. You can create a private variable of the class as follows:
Copy codeThe Code is as follows:
Var baz;
(Function (){
Var foo = 10;
Var bar = 2;
Baz = function (){
Return foo * bar;
};
})();
Baz ();

Although executed outside the anonymous function, baz can still access foo and bar.

Note:

1, 1st rows. baz is a global variable;

2, 3rd ~ Row 3 defines an anonymous function;

3, 4th, and 5 rows. foo and bar are local variables in the anonymous function. 6th ~ Line 8: Define an anonymous function in the anonymous function and assign it to the global variable baz;

Lines 4 and 10th call baz. If it is changed to "alert (baz ();", 20 is displayed;

5. It is reasonable to say that foo and bar cannot be accessed outside the anonymous function, but now we can.

Before you describe the closure, read about the anonymous function.



Anonymous Functions
Anonymous functions are functions that do not need to define function names. Anonymous functions are the same as Lambda expressions. The only difference is that the syntax format is different. Lambda expressions go further. Essentially, they all act as: the production method-the inline method, that is, the function definition is omitted and the function body is directly written.

Lambda expressions:

(Input parameters) =>{ statement ;}
Where:

Parameter List, which can have multiple, one, or no parameters. Parameters can be implicitly or explicitly defined.
Expression or statement block, that is, the function body.
Code above, 6th ~ In the eight rows, there is no function name, and it is an anonymous function. It adopts Lambda expressions. Strictly speaking, although there are differences in syntax, the purpose is the same.

Example 1:
Copy codeThe Code is as follows:
Var baz1 = function (){
Var foo = 10;
Var bar = 2;
Return foo * bar;
};
Function mutil (){
Var foo = 10;
Var bar = 2;
Return foo * bar;
};
Alert (baz1 ());
Var baz2 = mutil ();
Alert (baz2 );

Note:

1. baz1 is exactly the same as baz2, but baz1 saves function definitions compared with baz2. direct function bodies -- look much more simple.



Closure
Variable Scope
Example 2: The function can access global variables.

Copy codeThe Code is as follows:
Var baz = 10;
Function foo (){
Alert (baz );
}
Foo ();


This is OK.

Example 3: The function cannot access local variables inside the function.

Copy codeThe Code is as follows:
Function foo (){
Var bar = 20;
}
Alert (bar );


This will report an error.

In addition, when a function declares a variable, the var keyword must be used. Otherwise, a global variable is declared.

Example 4:

Copy codeThe Code is as follows:
Function foo (){
Bar = 20;
}
Alert (bar );


External function access to local variables in a function
Actually, we need to obtain the local variables inside the function from outside the function. First, let's look at Example 5.

Example 5:

Copy codeThe Code is as follows:
Function foo (){
Var a = 10;
Function bar (){
A * = 2;
}
Bar ();
Return;
}
Var baz = foo ();
Alert (baz );


A is defined in foo, and bar can be accessed, because bar is also defined in foo. Now, how can I make the bar be called outside foo?

Example 6:

Copy codeThe Code is as follows:
Function foo (){
Var a = 10;
Function bar (){
A * = 2;
Return;
}
Return bar;
}
Var baz = foo ();
Alert (baz ());
Alert (baz ());
Alert (baz ());

Var blat = foo ();
Alert (blat ());


Note:

1. Now you can access a from outside;

2. The JavaScript scope is lexical. A runs in the foo defined by it, rather than in the scope of calling foo. As long as bar is defined in foo, it can access the variable a defined in foo even if the execution of foo has ended. That is to say, after "var baz = foo ()" is executed, foo has been executed and a should not exist, but then baz is called to find that a still exists. This is one of the characteristics of JavaScript-running in definition, rather than running calls.

"Var baz = foo ()" is a reference to the bar function; "var blat = foo ()" is a reference to another bar function.

Use closures to implement Private Members
Now, you need to create a variable that can only be accessed within the object. You can use closures to create variables that only allow access to specific functions, and these variables still exist between calls of these functions.

To create a private property, you need to define relevant variables in the scope of the constructor. These variables can be defined for all function access in the scope, including those privileged methods.

Example 7:

Copy codeThe Code is as follows:
Var Book = function (newIsbn, newTitle, newAuthor ){
// Private attributes
Var isbn, title, author;
// Private Method
Function checkIsbn (isbn ){
// TODO
}
// Privileged method
This. getIsbn = function (){
Return isbn;
};
This. setIsbn = function (newIsbn ){
If (! CheckIsbn (newIsbn) throw new Error ('book: Invalid ISBN .');
Isbn = newIsbn;
};
This. getTitle = function (){
Return title;
};
This. setTitle = function (newTitle ){
Title = newTitle | 'no title specified .';
};
This. getAuthor = function (){
Return author;
};
This. setAuthor = function (newAuthor ){
Author = newAuthor | 'no author specified .';
};
// Constructor code
This. setIsbn (newIsbn );
This. setTitle (newTitle );
This. setAuthor (newAuthor );
};

// Common and non-specific methods
Book. prototype = {
Display: function (){
// TODO
}
};


Note:

1. Declare the isbn, title, and author variables with var, instead of this, which means they only exist in the Book constructor. The same is true for checkIsbn functions because they are private;

2. to access private variables and methods, you only need to declare them in the Book. These methods are called privileged methods. Because they are public methods, but they can access private variables and private methods, such as getIsbn, setIsbn, getTitle, setTitle, getAuthor, setAuthor (accessors and constructors ).

3. In order to access these privileged Methods outside the object, this keyword is added to the front of these methods. Because these methods are defined in the scope of the Book constructor, they can access private variables isbn, title, and author. However, when the isbn, title, and author variables are referenced in these privileged methods, this keyword is not used, but directly referenced. Because they are not public.

4. Any method that does not need to directly access private variables, as stated in Book. prototype, such as display. It does not need to directly access private variables, but is accessed through get * or set * Introduction.

5. objects created in this way can have real private variables. Other users cannot directly access any internal data of the Book object. They can only use the value assignment tool and. In this way, everything is under control.

However, the disadvantage of this method is:

In the "portal large-size" Object creation mode, all methods are created in the prototype object of the prototype. Therefore, no matter how many object instances are generated, these methods have only one copy in the memory.
In this section, if no new object instance is generated, each private method (for example, checkIsbn) and privileged method (for example, getIsbn, setIsbn, getTitle, setTitle, getAuthor, and setAuthor) generate a new copy.
Therefore, this method is only suitable for private members. In addition, this method is not conducive to inheritance.

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.