Parsing the scope and closure of JS--starting with a classic face question

Source: Internet
Author: User

How to understand the scope of JS, closures, private variables, the This object concept?

Let's start with a classic face test!

Title: Create 10 <a> tags, click time to pop up the corresponding serial number

Think about it, then open it.
     // think about what you're going to write about, isn't it?        But the result, the bounce is 10, why?           var  i,a     for (i=0;i<10;i++) {          a=document.createelement (' A ')          a.innerhtml=i+ ' <br> '          a.addeventlistener (' click ',function (event) {               var event=event| | window.event               event.preventdefault ()               alert (i)                            })          Document.body.appendChild (a)     } 
View Code

The answer to this question at the end, of course, you can go straight to the end to understand, but I do not recommend this!!

Related to today's variables, scopes, closures and so on, in the variables, scope of knowledge has been said some, and then re-simple to say.

execution Environment : Also known as the execution context, two, one is the Global Environment (window), one is the function environment (each function is a function environment)

Scope chain : Contemporary code executes in an environment, creating a scope chain of variable objects to guarantee orderly access to all variables and functions that the execution environment has access to. The external environment is inaccessible to the internal environment, and the internal environment can be accessed through the scope chain.

block-level scope : JS has no block-level scope, similar to the loop statement, conditional judgment statement within the scope is global; only two execution environments

variable : The var operator determines whether it is a local variable or a global variable.

Browser parsing: In the browser parsing, all the variables are promoted first, the variables are saved as undefined, when the execution of the line to give the assignment; the function declaration is complete at the beginning, and the function expression is the same as the parse variable.

     Console.log (a)         //undefined     var a=100     console.log (a)         //100          Person ("double")       //double,20       functions Person (name) {//Declaration function          Age =20          console.log (name,age)          var      }

This: the object that references the execution environment, which can be confirmed only at execution time and cannot be confirmed when defined

        //an ordinary constructor; This is an instance of a constructor function .        functionFoo (name) {//var this             This. name=name//return This        }        varf=NewFoo ("Double")        //ordinary object; This is the object.        varobj={name:"Double", Printname:function() {Console.log ( This. Name)} } obj.printname ()//normal function This is the window        functionfn () {Console.log ( This)} fn ()//Call apply bind to set the value of this        functionfn1 (name,age) {alert (name) Console.log ( This)} fn1.call ({x:[+], ' double ', 20)//This is the object {x:100}Fn1.apply ({x:100},["double", 20])//This is the object {x:100}        varFn2=function(name,age) {alert (name) Console.log ( This)}.bind (' Double ', 20)//this is double.FN2 ()
Closed Package

This concept is somewhat abstract, so to understand: a function that has access to a variable in another function scope, which means that one function can access a variable in another function scope

Generally two places, one as the return value, one as the passed parameter

//Closed Package//function as return valuefunctionF1 () {vara=100; //returns a function (function as return value)    return function(){Console.log (A)}}//F1 get a functionvarf1=F1 ()vara=200F1 ()//a=100 executes the return function, and the function finds the variable (not the scope of the executing function) in the scope of the defined function, and does not find the parent scope//function as a parameter passfunctionF1 () {vara=100return function() {Console.log (A)}}varF1=F1 ()//It's a function .functionF2 (FN) {vara=200fn ()} F2 (F1)//a=100 to the function to F2

Take the closure as the return value as an example, say a little bit more

This is an example of a closure to return a value
functionCreate () {vara=100return function() {Console.log (A)}}vara=200varResult=create ()//Get Return functionResult ()//executing the return function The A=100 function looks in the scope of the defined function and then finds it in the parentwhen a function is called, an execution environment and the corresponding scope chain are created, the active object of the function is initialized with arguments and other parameters, but in the scope chain, the active object of the outer function is always the second, and for the anonymous function inside the CREATE function, the The domain chain is initialized with three active objects, one for itself, one for the CREATE function, and one for the global environment. In general, the function is executed and the active object is destroyed; But for closures, when the CREATE function finishes, the active object of the function is not destroyed. Because the internal anonymous function always references the active object in it

Look at this again.

     //a method of a normal object     varperson={name:"Double", GetName:function() {Console.log ( This. Name)} } person.getname ()//Double          //the Normal object method returns an anonymous function     varperson={name:"Double", GetName:function(){                  return function() {Console.log ( This. Name)} }     }     varName= "single"Person.getname () ()// Single        //the Normal object method returns an anonymous function     varperson={name:"Double", GetName:function(){              varthat= This           //The variable assigned to that by this object before the anonymous function is defined is about the same as this and arguments, and assigns it to a variable              return function() {Console.log (That.name)}}} varName= "single"Person.getname () ()//Double

OK, after understanding the closure, scope chain knowledge, back to the interview question, you should know the reason

The correct wording
varI for(i=0;i<10;i++){ (function(i) {varA=document.createelement (' a ') a.innerhtml=i+ ' <br> 'A.addeventlistener (' Click ',function(event) {varevent=event| |window.event Event.preventdefault () alert (i)//go to Parent scope lookup}) Document.body.appendChild (A)}) (i)}//JS has no block-level scope, so I of alert (i) is in the global scope, and the return is of course ten, //How do I let I bounce out of each one? //we know that the environment is divided into functional environment and global environment, only need to have their own execution environment for each I can //How do you do that? //directly add a self-executing function, so that each i has its own function environment, that is, to build a private scope
Memory leaks

Because of the existence of closures, the variables of the external function are always referenced, the closure does not end, the reference is always present, and the memory is not recycled

       //Memory Leaks       functionPerson () {varElement=document.getelementbyid ("Someelement") Element.onclick=function() {alert (element.id)}}//Resolving memory leaks       functionPerson () {varElement=document.getelementbyid ("Someelement")              varId=element.id//assign the required content to a variableelement.onclick=function() {Alert (id)} element=NULL         //The closure refers to the entire active object containing the function, which contains the element}
Mimic block-level scopes

All know, JS does not block-level scope, so to imitate, how to imitate it?

The above-mentioned question has been told: the function environment is constructed by an anonymous function to form a private scope

The following explains something about anonymous functions, function declarations, function expressions, description of block-level scopes

     //A variable name is just another form of a value     varcount=10alert (count) alert (10)           //since the variable is possible, what about the function?     varperson=function() {alert ("Hello")} person ()varperson=function() {alert ("Hello")     }()          function() {alert ("Hello")     }()    //Error     //why not? Because JS takes the function keyword as the start of a declaration of functions, the function declaration cannot be parenthesized          (function() {alert ("Hello")     })()     //To convert a function declaration to a function expression, you can add parentheses to the outside, that is, to form your own private scope

Read Uncle Tom's blog about this, and he said so.

     //conversions for function declarations and function expressions     //JS bracket () is not included in the statement, and JS in the &&,| |, comma and other operators are in function expressions and function declarations to disambiguate     //so     varI=function() {Console.log ("Hello")}()     true&&function() {Console.log ("Hello")}()     0,function() {Console.log ("Hello")}()     !function() {Console.log ("Hello")}()     ~function() {Console.log ("Hello")}()     -function() {Console.log ("Hello")}()     +function() {Console.log ("Hello")}()     New function() {Console.log ("Hello")}     varvalue=10New function() {Console.log (value)} (value)//Parentheses Pass Parameters

So much for the knowledge of closures.

Parsing the scope and closure of JS--starting with a classic face question

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.