JavaScript Basics-variables, scopes, and memory issues

Source: Internet
Author: User
Tags getcolor

As defined by ECMA-262, JavaScript variables differ greatly from those of other languages. The nature of the loosely typed JavaScript variable determines just one name that is used to hold a particular value at a specific time. Because there is no rule that defines what data type values A variable must hold, the value of the variable is the data type that can be changed within the declaration period of the script. Although this may be an interesting and powerful but also problematic feature in some way, JavaScript variables are actually much more complex.

values for base types and reference types

The ECMAScript variable may contain values for two different data types: the base type and the reference type value. Primitive type values refer to simple data segments, whereas reference types refer to objects that consist of multiple values.

When assigning a value to a variable, the parser must determine whether the value is a base type value or a reference type value. Basic data type: Undefined, Null, Boolean, number, and string. These 5 basic data types are accessed by value because you can manipulate the actual values that are saved in the variable.

The value of a reference type is an object that is saved in memory. Unlike other languages, JavaScript does not allow access to in-memory locations, which means that the object's memory space cannot be manipulated directly. When you manipulate an object, you are actually manipulating the object's reference rather than the actual object. To do this, the value of the reference type is accessed by reference.

Dynamic Properties

You define a primitive type value and a reference type value in a similar way: Create a variable and assign a value to the variable. However, when this value is saved to a variable, the actions that can be performed on the different types of values are quite divergent. For values of reference types, we can add properties and methods to them, and you can change and delete their properties and methods. Such as:

var person = new Object ();

Person.name = "Nicholas";

alert (person.name);//nicholas

The above code creates an object and saves it in the variable person, and then we add a property named Name to the object and assign the string "Nicholas" to this property. The new property is then accessed through the alert () function. This property will persist if the object is not destroyed or if the property is not deleted.

However, you cannot add a property to a base type value, although doing so does not cause any errors. Like what:

var name = "Nicholas";

Name.age = 27;

alert (name.age);//undefined

In this example, a property named age is defined for the string name, and the property is assigned a value of 27. However, when this property is accessed, the attribute is found to be missing. This means that you can only add properties dynamically to reference type values for future use.

Copy variable values

In addition to the way it is saved, there is a difference between assigning a base type and a reference type value to another variable from one variable. If you copy the value of the base type from one variable to another, a new value is created on the variable object, and the value is copied to the location where the new variable is assigned. After this, two values do not affect each other.

When a value of a reference type is copied from one variable to another, the value in the variable object is also copied to the space allocated for the new variable. The difference is that a copy of this value is actually a pointer to an object stored in the heap. When the copy operation is finished, two variables will actually refer to the same object. Therefore, changing one of the variables will affect the other variable.

The parameters of all functions in ECMAScript are passed by value. In other words, copying the values from the outside of the function to the parameters inside the function is the same as copying the value from one variable to another. The delivery of a primitive type value is the same as a copy of a primitive type variable, whereas a reference type value is passed as a copy of a reference type variable.

The value passed when the value of the base type is passed to the parameter is copied to a local variable (that is, a named parameter, or, in the ECMAScript concept, an element in the arguments object). When a value of a reference type is passed to a parameter, the address of the value in memory is copied to a local variable, so the change of the local variable is reflected outside the function. Such as:

function addten (num) {

Num +=10;

return num;

}

var count = 20;

var result = Addten (count);

alert (count); //20 No change

alert (result); //30

Here the function Addten () has a parameter num, and the argument is actually a local variable of the function, when the function is called, the variable count is passed to the function as a parameter, and the value of the variable is 20. The value 20 is then copied to the parameter num for use in Addten (). Inside the function, the value of the parameter num is added to 10, but this change does not affect the count variable outside the function. The parameter num and count do not know each other, they just have the same value. When adding num is passed by reference, the value of the variable count is also changed to 30, which reflects the changes inside the function. Of course, using basic types such as numerical values to illustrate the placement of pass parameters is relatively simple, but if you use objects, then the problem is not very good understanding, such as:

function setName (obj) {

Obj.name = "Nicholas";

}

var person =new Object ();

SetName (person);

alert (person.name); //nicholas

The above code creates an object and saves it in the variable person. The object is then passed to the SetName () function and is then copied to obj. Inside this function, obj and person refer to the same object. In other words, even if the object is passed by value, obj accesses the same object by reference. Therefore, when you add the Name property to obj inside the function, the person outside the function will also be reflected, because the object pointed to by person has only one and global object in the heap memory. Again such as:

function setName (obj) {

Obj.name = "Nicholas";

obj = new Object;

Obj.name = "Greg";

}

var person =new Object ();

SetName (person);

alert (person.name); //nicholas

In the above example, if the person is passed by reference, the person is automatically modified to point to a new object whose Name property has a value of "Greg", but the value displayed is still "Nicholas" when the Person.name is next accessed. This means that even if the value of the parameter is modified inside the function, the original reference remains unchanged. In fact, when you rewrite obj inside a function, the variable refers to a local object. This local object is destroyed immediately after the function is executed.

Detection Type

To detect whether a variable is a basic type, the TypeOf operator is the best tool. If the value of the variable is an object or null, the TypeOf operator returns "Object".

Although TypeOf is a very powerful helper when detecting a basic data type, this operator is not useful when detecting values of reference types. In general, we do not want to know that a value is an object, but rather to know what type of object it is. To do this, ECMAScript provides the instanceof operator, syntax:

result = Variable instanceof constructor

If the variable is an instance of a given reference type, then the instanceof operator returns TRUE.

As a rule, all reference types have values that are instances of object. Therefore, the instanceof operator always returns True when a reference type and an object constructor are instrumented. Of course, if you use the instanceof operator to detect a value of a base type, the operator always returns false because the base type is not an object.

execution Environment and scope

The execution Environment (ExecutionContext, which is sometimes referred to as "environment" for simplicity) is one of the most important concepts in JavaScript. The execution environment defines the other data that a variable or function has access to, and determines 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 the object. Although the code we write does not have access to this object, the parser uses it in the background when it processes the data.

The global execution environment is one of the outermost execution environments. Depending on the hosting environment where the ECMAScript implementation resides, the objects that represent the execution environment are different. In a Web browser, the global execution environment is considered a Window object, so all global variables and functions are created as properties and methods of the Window object. After all code in an execution environment is executed, the environment is destroyed, and all variables and function definitions stored therein are destroyed (the global execution environment is not destroyed until the application exits-for example, when the Web page or browser is closed).

Each function has its own execution environment. When the execution flow enters a function, the environment of the function is pushed into an environment stack. After the function executes, the stack pops up its environment and returns control to the previous environment. The execution flow in the ECMAScript program is controlled by this convenient mechanism.

When code executes in an environment, a scope chain of variable objects is created (scope chain). The purpose of a scope chain is to ensure access to all variables and functions that the execution environment has access to. The front end of the scope chain, which is always the variable object for the environment in which the code is currently executing. If the environment is a function, its active object is used as a variable object. A multi-action object initially contains only one variable, the arguments object (this object does not exist in the global environment). The next variable object in the scope chain comes from the containing (external) environment, and the next variable object comes from the next containment environment. In this way, it continues to the global execution environment; The variable object of the global execution environment is always the last object in the scope chain.

Identifier parsing is the process of searching identifiers one level at a scope chain. The search process always starts at the front end of the scope chain, and then goes backward backwards until the identifier is found (if an identifier is not found, this usually results in an error).

Example:

var color ="Blue";

function ChangeColor () {

if (color = = ="Blue") {

color = "Red";

}Else{

color = "Blue";

}

}

ChangeColor ();

Alert ("Color is now" + color);

In this simple example, the scope chain of the function ChangeColor () contains two objects: its own variable object (which defines the arguments object) and the variable object of the global environment. You can access the variable color inside the function so that it can be found in this scope chain.

In addition, variables defined in the global scope can be used interchangeably with global variables in a local environment, such as:

var color ="Blue";

function ChangeColor () {

var anothercolor ="Red";

function swapcolors () {

var tempcolor = Anothercolor;

Anothercolor= color;

color = Tempcolor;

// Here you can access Color , Anothercolor and the Tempcolor

}

// Here you can access Color and the Anothercolor , but cannot access Tempcolor

Swapcolors ();

}

// This can only be accessed Color

ChangeColor ();

The above code covers 3 execution environments: The global environment, the local environment of the ChangeColor (), and the local environment of the swapcolors (). There is a variable color and a function changecolor () in the global environment. The local Environment of ChangeColor () is a variable named Anothercolor and a function named Swapcolors (), but it can also access variable color in the global environment. The local Environment of Swapcolors () has a variable tempcoloe, which can only be accessed in this environment. Local environments, whether global or ChangeColor (), do not have access to tempcolor. However, within swapcolors (), you can access all the variables in the other two environments, because those two environments are its parent execution environment.

extend the scope chain

Although there are two types of execution environments-Global and local (functions)-There are other ways to extend the scope chain. This is because some statements can temporarily add a variable object to the front end of the scope chain, and the variable object is removed after the code executes. This behavior can occur in both cases. Specifically, the scope chain is extended when the execution stream enters any of the following statements:

(1) Catch block for Try-catch statements

(2) With statement

Both statements add a variable object to the front of the scope chain. For the WITH statement, the specified object is added to the scope chain. For a catch statement, a new variable object is created that contains the declaration of the thrown error object. Such as:

function BuildUrl () {

var qs ="Debug=true";

with (location) {

var url = href + qs;

}

return URL;

}

Here, the WITH statement receives the location object, so its variable object contains all the properties and methods of the Location object, and the variable object is added to the front end of the scope chain. A variable QS is defined in the BuildUrl () function. When the variable href is referenced in the WITH statement (actually referencing location.href), it can be found in the variable object of the current execution environment. When referring to the variable QS, the variable that is defined in BuildUrl () is referenced in the variable object in the function environment. As for the inside of the WITH statement, a variable named URL is defined, so the URL becomes part of the function execution environment, so it can be returned as the value of the function.

no block-level scopes

JavaScript without block-level scopes often leads to confusion in understanding. In other languages of Class C, blocks of code that are enclosed by curly braces have their own scopes, and thus support the definition of variables based on conditions. In Java, the following statement will prompt for an error:

{

int a = 10;

}

System. out. println (a);

In JavaScript, the following statement executes normally:

{

var a = 10;

}

alert (a);

Again such as:

if (true) {

var color ="Blue";

}

alert (color);

Here is the variable color defined in an if statement. If it is in C, C + +, or Java, color is destroyed after the IF statement has finished executing. In JavaScript, however, a variable declaration in an If statement adds a variable to the current execution environment (in this case, a global variable). This difference is especially true when using a for statement, for example:

for (Var i=0;i<10;i++) {

DoSomething (i);

}

alert (i);//10

For a block-scoped language, the variables defined by the expression of the for-statement initialization variable will only exist in the context of the loop. For JavaScript, the variable I created by the for statement will still exist in the execution environment outside the loop even after the for loop execution has ended.

declaring Variables

Variables declared with Var are added to the closest environment. Within the function, the closest environment is the local environment of the function, and in the With statement, the closest environment is the function environment. If you initialize a variable without using the var declaration, the variable is automatically added to the global environment, such as:

function Add (NUM1, num2) {

var sum = num1 + num2;

return sum;

}

var result = Add (10, 20); //30

alert (sum); // because sum is not a valid variable and therefore causes an error

The function add () in the above code defines a local variable named sum that contains the result of the addition operation. Although the result value is returned from the function, the variable sum is not accessible outside the function. If you omit the var keyword from this example, sum will also be accessible when add () finishes executing.

Query Identifiers

When you reference an identifier in an environment for reading or writing, you must search to determine what the identifier actually represents. The search process starts from the front end of the scope and queries the identifier that matches the given name up. If the identifier is found in the local environment, the search process stops and the variable is ready. If the variable name is not found in the local environment, it continues to search up the scope chain. The search process goes back to the variable object of the global environment. If the identifier is not found in the global environment, it means that the variable is not yet declared. Such as:

var color = "Blue";

function GetColor () {

Returncolor;

}

Alert (GetColor ());//"Blue"

Calling the function GetColor () in this example will refer to the variable color. In order to determine the value of the variable color, the search process begins with a volume step. First, search for a variable object of GetColor () to find out if it contains an identifier named color. In the case where it is not found, the search continues to the next variable object (the variable object of the global environment), and then where the identifier named color is found. Because a variable object that defines the variable is searched, the search process is declared closed.

In this search process, if there is a local definition of the variable, the search stops automatically and no longer enters another variable object. In other words, if there is an identifier with the same name in the local environment, the identifier in the parent environment will not be used, such as:

var color = "Blue";

function GetColor () {

Varcolor = "Red";

Returncolor;

}

Alert (GetColor ());//"Red"

The modified code declares a local variable named color in the GetColor () function. When the function is called, the variable is declared. When the second line of code in the function executes, it means that the value of the variable color must be found and returned, and the search process begins with the local environment, where a variable named color is found with a value of "red". Because the variable is already found, the search stops immediately, the return statement uses the local variable, and returns "red" for the function. That is, any code that follows the declaration of a local variable color cannot access the global variable color variable without using Window.color. If one of the operands is an object and the other is not, the valueof () method is called on the object to obtain a value of the base type to compare against the previous rule.

Garbage Collection

JavaScript has an automatic garbage collection mechanism, which means that the execution environment is responsible for managing the memory used during code execution. In languages such as C and C + +, a basic task for developers is to manually track memory usage, which is a source of many problems. When writing JavaScript programs, developers no longer care about memory usage issues, the allocation of required memory, and the recycling of useless memory are fully automated management. The rationale for this garbage collection mechanism is simple: identify variables that are no longer in use, and then release the memory they occupy. To do this, the garbage collector periodically performs this operation at a fixed time interval (or a predetermined collection time in code execution).

Local variables exist only during the execution of a function. In this process, the local variables are allocated the appropriate space on the stack (or heap) memory to store their values. These variables are then used in the function until the function execution is finished. At this point, there is no need for local variables to exist, so they can be freed up for future use. In this case, it is easy to determine whether the variable is still necessary, but not all the circumstances are so easy to reach a conclusion. The garbage collector must keep track of which variables are useful and which ones are useless, marking variables that are no longer useful for future recall of their occupied memory. The policy used to flag the useless variable may be implemented, but there are typically two policies that are specific to the implementation in a browser.

Mark Clear

The most common method of garbage collection in JavaScript is tag Cleanup (mark-and-sweep). When a variable enters the environment (for example, when declaring a variable in a function), the variable is marked as "entering the environment." Logically, it is never possible to release the memory used by variables entering the environment, because they may be consumed as long as the execution flow enters the appropriate environment. When the variable leaves the environment, it is marked as "out of the environment."

You can use any way to tag variables. For example, you can record when a variable enters the environment by flipping a particular bit, or use a "go to environment" variable list that is a "leave the Environment" list to track which variable has changed. In the final analysis, how to tag variables is not important, but the key is to adopt any strategy.

The garbage collector will tag all of my variables stored in memory when it is running (you can use any of these tags, of course). It then removes variables from the environment and tags of variables that are not already referenced by variables in the environment. Variables that are tagged later will be considered as variables to be deleted because variables in the environment are inaccessible to those variables. Finally, the garbage collector completes the memory cleanup work, destroys those tagged values, and reclaims the memory space that they occupy.

Reference Count

Another less common garbage collection strategy is called Reference Counting (referencecounting). The meaning of the reference count is the number of times each value is referenced by the tracking record. When a variable is declared and a reference type value is assigned to the variable, the number of references to that value is 1. If the same value is assigned to another variable, the number of references to that value is added by 1. Conversely, if a variable that contains a reference to this value has another value, the number of references to the value is reduced by 1. When the number of references to this value becomes 0 o'clock, it means that there is no way to access the value again, so you can reclaim the memory space it occupies. That way, when the garbage collector runs again next time, it frees up the space occupied by those values that have a zero reference count.

Performance Issues

The garbage collector is run periodically, and if the amount of memory allocated to the variable is considerable, the amount of garbage collected by the demon is quite large. In this case, determining the time interval for garbage collection is a very important issue. When it comes to how often the garbage collector runs, it makes people think of IE's notorious performance issues. IE's garbage collector runs according to the amount of memory allocated, specifically 256 variables, 4,096 objects (or array) literals and arrays of elements (slots), or 64KB strings. If any of these thresholds are reached, the garbage collector runs. The problem with this implementation is that if a script contains so many variables, it is likely that the script will keep so many variables in its declaration cycle. In this way, the garbage collector will have to run frequently, resulting in a serious heart-energy problem prompting IE7 to rewrite its garbage collection routines.

With the release of IE7, its JavaScript engine's junk phone routine has changed the way it works: The variable allocation literal that triggers the spam phone and (or) the threshold value of the array is adjusted for the attack table correction. The critical values in the IE7 are equal to IE6 at the initial time. If the garbage collection routine reclaims less than 15% of the memory allocated, the thresholds for variables, literals, and (or array) elements are doubled. If the routine reclaims 85% of the memory allocations, resets the various thresholds to the default values. This seemingly simple adjustment greatly improves the performance of IE when running pages that contain a lot of JavaScript.

In fact, the garbage collection process can be triggered in some browsers, but it is not recommended. In IE, call window. The CollectGarbage () method performs garbage collection immediately. In Opera7, which is later, calling Window.opera.collect () also initiates the garbage collection routine.

Managing Memory

By using a language that has a garbage collection mechanism, developers generally do not have to worry about memory management issues. However, the problems that JavaScript faces in memory management, or garbage collection, are a bit different. One of the main problems is that the amount of available memory allocated to a Web browser is typically less than that allocated to a desktop application. This is done primarily for security reasons, in order to prevent the Web page running JavaScript from exhausting all system memory and causing the system to crash. Memory throttling issues not only affect allocating memory to variables, but also affect the call stack and the number of statements that can be executed concurrently in one thread.

Therefore, make sure that you use the least amount of memory for better performance on your page. The best way to optimize memory consumption is to save only the necessary data for the code in execution. Once the data is no longer useful, it is preferable to set it to NULL to release its reference-this is called dereferencing. This practice applies to most global variables and properties of global objects. Local variables are automatically dereferenced when they leave the execution environment, such as:

function Createperson (name) {

var localperson =new Object ();

Localperson.name = name;

return Localperson;

}

var globalperson = Createperson ("Nicholas");

// Manual Release Globalperson the reference

Globalperson = null;

In this example, the variable Globalperson gets the value returned by the Createperson () function. Inside the Createperson (() function, an object is created and assigned to the local variable Localperson, and a property named name is added to the object. Finally, when this function is called, Localperson returns and assigns a value to the global variable Globalperson as a function value. Since Localperson has left its execution environment after the Createperson () function has been executed, it is not necessary to explicitly dereference it at a time. But for the global variable Globalperson, it needs to be de-referenced manually when it is not used, which is the last line of code in the example above.

However, releasing a reference to a value does not mean that the memory consumed by the value is automatically reclaimed. The real effect of dereferencing is to leave the value out of the execution environment so that it can be reclaimed the next time the garbage collector runs.

JavaScript Basics-variables, scopes, and memory issues

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.