JavaScript from the scope chain to talk about closure _javascript skills

Source: Internet
Author: User
Tags closure define local getdate

God's horse is a closed bag.
On the concept of closures, the woman said that the woman is reasonable.

A closure is a function that has access to a variable in another function's scope
The concept is a bit round and split. Conceptually, closures have two features:

    • 1. function
    • 2, access to another function in the scope of variables

Before Es 6, JavaScript had only the concept of functional scope, and there was no block-level scope (but catch-caught exceptions can only be accessed in Catch blocks) (Iife can create local scopes). Each function scope is closed, that is, the external is inaccessible to the variables in the scope of the function.

function GetName () {
 var name = "Beauty's name";
 Console.log (name);  "Beauty's name"
}
function DisplayName () {
 console.log (name);//Error
}

But in order to get the name of a beautiful woman, the single Wang who never gave up the code changed to this:

function GetName () {
 var name = "Beauty's name";
 function DisplayName () {
 console.log (name); 
 }
 return displayName;
}
var beauty = GetName (); 
Beauty ()//"Belle's name"

This, beauty is a closure, single Wang want How to play on how to play. (but do not recommend single Wang in Chinese to do variable name, we do not learn).

About the closure, but also want to say three points:
1, closures can access variables other than the current function

function Getouter () {
 var date = ' 815 ';
 function GetDate (str) {
 console.log (str + date);//access external date
 } return
 getDate (' Today is: ');//"Today is: 815"
}
Getouter ();

GetDate is a closure that, when executed, forms a scope a,a and does not define a variable date, but it can find the definition of the variable in the parent-level scope.

2, even if the external function has returned, the closure can still access the variables defined by the external function

function Getouter () {
 var date = ' 815 ';
 function GetDate (str) {
 console.log (str + date);//access external date
 } return
 getDate;  The external function returns
}
var today = Getouter ();
Today (' Now is: '); "Today is: 815"
(' Tomorrow is not: ');//"Tomorrow is not: 815"

3, closures can update the value of external variables

function Updatecount () {
 var count = 0;
 function GetCount (val) {
 count = val;
 Console.log (count);
 }
 return getcount;  External function returns
}
var count = Updatecount ();
Count (815); 815
count (816);//816

Scope chain
What about a variable that can access an external function for a fur closure? This is going to talk about the scope chain in JavaScript.
JavaScript has a concept of an execution environment (execution context) that defines other data that a variable or function has access to, determining their respective behavior. Each execution environment has a variable object associated with it, and all variables and functions defined in the environment are stored in this object. You can think of it as a normal object of JavaScript, but you can only modify its properties, but you cannot reference it.

The variable object also has a parent scope. When a variable is accessed, the interpreter first looks for the identifier in the current scope and, if it is not found, goes to the parent scope until the variable's identifier is found or the parent scope is no longer present, which is the scope chain.

The scope chain and prototype inheritance are somewhat similar, but there is a slight difference: if you look for an attribute of a normal object, it returns undefined if it is not found in the current object and its prototype, but the lookup property is thrown referenceerror if it does not exist in the scope chain.

The top of the scope chain is the global object. For code in the Global environment, the scope chain contains only one element: a global object. Therefore, when you define variables in the global environment, they are defined in the global object. When a function is called, the scope chain contains more than one scope object.

    • Global Environment

A little bit more about the scope chain (the Red Book has a detailed explanation of the scope and execution environment), look at a simple example:

My_script.js
"Use strict";
var foo = 1;
var bar = 2;

In the global environment, two simple variables are created. As previously mentioned, the variable object is a global object.

    • non-nested functions

Change the code to create a function that has no nested functions:

"Use strict";
var foo = 1;
var bar = 2;
function MyFunc () {
 //--define local-to-function variables
 var a = 1;
 var b = 2;
 var foo = 3;
 Console.log ("Inside MyFunc");
}
Console.log ("Outside");
--and then, call it:
MyFunc ();

When MyFunc is defined, the myfunc identifier (identifier) is added to the current scope object (in this case, the global object), and the identifier refers to a function object. The function object contains the source code for the function and other properties. One of the attributes we care about is the internal attribute [[scope]]. [[scope]] refers to the current scope object. That is, when the identifier of the function is created, the scope object that we are able to access directly (here is the global object).

The more important point is that the function object that MyFunc refers to does not just contain the code of the function, but also contains the scope object that points to the time it was created.

When the MyFunc function is called, a new scope object is created. The new Scope object contains the local variable defined by the MyFunc function, along with its arguments (arguments). The parent scope object of this new scope object is the scope object that we can directly access when running MyFunc.

    • Nested functions

As mentioned earlier, when a function returns without being referenced, it is reclaimed by the garbage collector. But for closures (function nesting is a simple way to form closures), even if the external function returns, the function object will still refer to the scope object when it was created.

"Use strict";
function Createcounter (initial) {
 var counter = initial;
 function increment (value) {
 counter + = value;
 }
 function get () {return
 counter;
 }
 return {
 increment:increment,
 get:get
 };
}
var myCounter = createcounter (MB);
Console.log (Mycounter.get ()); Return
mycounter.increment (5);
Console.log (Mycounter.get ()); Return 105

When Createcounter (100) is invoked, both the inline function increment and get have references to the createcounter scope. If Createcounter (100) does not have any return value, then the createcounter scope is no longer referenced, so it can be garbage collected. But because Createcounter actually has a return value and the return value is stored in the myCounter , the reference relationship between the objects changes.

It takes some time to think that even though Createcounter has returned, its scope is still there and can only be accessed by inline functions. You can access the scope of Createcounter directly by calling Mycounter.increment () or Mycounter.get ().

When mycounter.increment () or Mycounter.get () is invoked, the new scope object is created, and the scope object's parent scope object is the scope object that is currently directly accessible.

When executed to return counter; , it is much more interesting to call increment (5) when the corresponding identifier is not found in the scope where get () is located, and it is looked up along the scope chain until the variable counter is found, and then the variable is returned. When increment (5) is called individually, the parameter value is stored in the current scope object. function to access value, you can immediately find the variable in the current scope. However, when the function is to access counter, it is not found, and then it looks up along the scope chain, and the corresponding identifier is found in the scope of Createcounter (), increment () The value of the counter is modified. In addition, there is no other way to modify this variable. The power of closures also lies in the ability to store private data.

Similar function objects, different scope objects
For the counter example above, say something about the extension. Look at the code:

Myscript.js
"Use strict";
function Createcounter (initial) {/
 * ... "*" code from previous example .../
}
//--Create counter Obje CTS
var myCounter1 = Createcounter (m);
var myCounter2 = Createcounter (200);

After MyCounter1 and MyCounter2 are created, the diagram is purple:

In the above example, the Mycounter1.increment and Mycounter2.increment function objects have the same code and the same attribute values (Name,length, etc.), but their [[scope]] is pointing to a different scope object.

This results in the following:

var a, B;
A = Mycounter1.get (); A equals
B = mycounter2.get ();//b equals
mycounter1.increment (1);
Mycounter1.increment (2);
Mycounter2.increment (5);
A = Mycounter1.get (); A is equal to the
mycounter2.get ();//b equals 205

Scope and this
The scope stores the variable, but this is not part of the scope, depending on how the function was called. For a summary of this point, you can read this article: JavaScript interview questions: Event delegates and this

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.