Analysis of JavaScript closures from a face test

Source: Internet
Author: User

It's said to be one of those five JavaScript questions that don't pay attention, and we'll see what the title looks like.

functionContainer (properties) {varObjthis = This;  for(varIinchproperties) {          (function(){                  vart =Properties[i]; objthis["Get" + i] =function() {returnt;}; objthis["Set" + i] =function(Val) {T =Val;};      })(); }  }     varProp = {Name: "Jim", age:13}; varCon =NewContainer (prop);     Console.log (Con.getname ()); Con.setname ("Lucy");  Console.log (Con.getname ()); Console.log (Prop.  Name); 

Now please write out the output of each console.log: ()

A:jim,lucy,lucy b:jim,jim,jim C:lucy, Lucy,lucy d:jim,lucy,jim

If you choose D to exclude the ingredients of luck, you may not have to look down because you can be sure that you are an experienced veteran.

If this is the alternative option, continue with the analysis below.

Let's start by scanning the entire container function: The function should be to add a get and set method to each property of the object being passed in.

Below begins a progressive analysis from top to bottom:

functionContainer (properties) {varObjthis = This;//Save a reference to this with Objthis     for(varIinchProperties) {//content in the loop properties(function(){            //This is the space created by the closure.          //a local variable is declared inside a closure to hold the value in the storage properties                vart =Properties[i]; //add two methods on a Objthis objectobjthis["get" + i] =function() {returnt;}; objthis["Set" + i] =function(Val) {T =Val;};  })(); //create an immediate function to form a closure, as we know that the function of a closure is that even after an outer function call, the outer function is not reclaimed immediately due to a closure reference, so the closure function can continue to use the variables and methods declared by the outer function.     }  }  
var prop = {Name: "Jim", Age:13};  var con = new Container (prop);  Console.log (Con.getname ());  Jim   con.setname ("Lucy");  Console.log (Con.getname ());  Lucy

At first glance, there is no problem, so where is this pit?

If we continue to print console.log (Prop. Name); Jim

Did you feel surprised? why Con.getname () get Lucy, while prop. Name get Jim?

===============================================================

We start with this immediate execution function, and if you omit it, then T is always the value after the loop. This immediately executes the function to solve the problem, so there is nothing wrong with it.

Then there is this objthis, which is an internal pointer to the container instance, and it has nothing to do with properties, but the properties and prop are related. Because prop is an object

is a reference type, so properties can be thought of as a copy of the prop reference (about JavaScript's arguments, and later on). So inside the container, you can modify the properties.

It is possible to change the prop itself, and of course can also access the properties of Prop.

I'll take a look.

var con = new Container (prop); What exactly does this con have?

    1. getage: 
    2. setage: function (val) {t = val;}
    3. getname: function () {return t;}
    4. setname: function (val) {return t;}

It appears that con is generating the corresponding Set/get method according to the attribute name of prop, but the method body cannot find the trace of properties. There was only one T, and

T=properties[i], this is not prop. The value of name or Prop.age? My first reaction was that there was a problem with the Set method. t = val; Common sense of assigning values based on object properties

var t = Prop. Name, t = ' xxx ', prop. The value of name is definitely not changed. This changes the only T itself.

Con.setname ("Lucy");  Console.log (Con.getname ());  Lucy
But why did the change take effect here?

I have been depressed in this place for a long time, I did not think clearly, and finally asked a senior predecessor to understand.

The reason is simple because the set and get methods on con have access to the value of t within the closure. There is no half-penny relationship with the properties.

Con.setname ("Lucy"); Equivalent to T = "Lucy", and con.getname equivalent to return t; This is a common truth.

This also explains why the value of Con.getname () is Lucy, and prop. Name or Jim.

Why do I have that kind of confusion? The reason is not to figure out this T, not to understand the use of closures. Now how to modify, in order to achieve the original intention of container?

Since the understanding of Con.setname modified is their own T,con.getname access is also its own T, then the only person to change this T prop.name just fine.

Here is the code I modified:

 function   Container (properties) { Span style= "color: #0000ff;"    >var  objthis = this   for  (var  i in   properties) {( function   () { var  name = I; objthis[ "Get" + i] = function  () {return
      Properties[name];}; objthis[ "Set" + i] = function  (val) {properties[name] = Val;};    })(); }}

Con.setname (' Frog ')
Console.log (Prop. Name,con.getname ());

Frog Frog

======================================================================

About the passing of parameters in JavaScript.

According to our knowledge of C, parameters are passed in two ways, passed by reference and passed by value.

But the parameters in JavaScript are all passed by value. This is true even if the parameter is the right image.

function Fun (a) {

}

var o = {name: ' Frog '}

Fun (o);

Fun (o/* Here is actually a reference to the O object is copied */)

This is not the point of this article, just a mention. Do not understand the private messages I or access to relevant information.

Analysis of JavaScript closures from a face test

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.