JavaScript Advanced Programming Chapter Fourth: variables, scopes, and memory issues

Source: Internet
Author: User

Directory

    • A reference to a variable
    • Execution Environment and scope
    • Scope chain Extension
    • Block-level scopes
    • Garbage collection mechanism
A reference to a variable

When a variable holds the basic data type, the operation of the variable (assignment, operation) is the operation of the basic data itself, even if it is an assignment operation, the value of the copy after the assignment and the previous value is independent of each other.

var a = 1;var b = ab++;console.log(a); //1console.log(b); //2

This is very well understood, but if a variable holds data of a reference type, such as an object, then the situation will be different because the variable holds not the object itself, but its address (pointer) in memory, so when assigning a value to a reference type, it is also copied, But the value after this copy is just a pointer, and all two of them point to a reference to the same object, so there is a problem of mutual influence.

var obj = new Object();var copyObj = obj;obj.name = 'test';console.log(obj2.name); //test

The graph representation is the following relationship:

The difference between the two is felt through concrete examples:

function PersonnelInfo(age, info) {    age = 10;    info.name = "cheng";}var info = {};var age = 0;PersonnelInfo(age, info);console.log(age);console.log(info);

As a result, we can conclude that there are two kinds of access to variables, one is "access by value", the other is "access by reference", and the operation variable by value access is the value itself, when the assignment is independent of each other, while the reference to access, and then to assign value, In fact, multiple variable access objects remain the same.

In general, we will save fixed-size values (such as the base data type) in the stack memory, the value of not fixed size (such as objects, arrays, etc.) to the heap memory, so the distinction is better use of memory space, improve execution efficiency.

Execution Environment and scope

There are two types of access to variables, access by value and access by reference, while the execution environment (execution context) forms a scope that determines whether a variable or function has permission to access data in another environment. This means that the execution environment determines whether certain identifiers can be accessed.

Each execution environment will have a corresponding variable object (Variable object), which is used to manage and save variables and functions (identifiers) in the current environment. When moving from one execution environment to another, the variable object is created first, and then the execution environment is added to the current execution stack, and if executed it is ejected from the execution stack, and the code, functions, and variables in the environment are destroyed.

There are two main types of execution environments in javascript: the global execution environment and the function execution environment. The global execution environment is bound to the Web browser top-level host object window, which means that the variables or functions we declare in the global execution environment will be the properties or methods of the Window object, and therefore the global execution environment will be destroyed only if you exit the browser or close the Web page.
The execution environment of a function is also a local execution environment, the variable object will be more special, we call it "active object", it is the default to save an identifier is arguments , and arguments stored in the function's parameters.

When the execution environment is added to the execution stack for execution, the JS engine parses the identifier based on the variable object, first it finds out whether the identifier in the current execution environment is defined in the variable object, if any, gets the value of the identifier for the next step, and if not, goes up to the upper-level execution environment, To access its variable object, and so on, and so on, the path of access to variable objects of different environments, like this, we can call the scope chain (scope chain).

Therefore, the so-called identifier parsing is actually the lookup of identifiers along the scope chain.
Access to the scope chain can only be accessed by the front and back, from the bottom up, not the opposite direction, and the concrete case code is visible:

var x = 1;function method(){    var y = 2;    console.log(x);}method();console.log(y); //Uncaught ReferenceError: y is not defined

Also visible:

Scope chain Extension

Some statements in JavaScript can extend the scope chain by adding a variable object at the front of the current scope chain.
For a with statement it adds the specified object as a variable object to the front end of the scope chain.

function buildUrl(){    var search = '?debug=true';    with(location){        var url = href + search; #注意with并没有作用域。    }    return url;}

For the catch statement, a new object is created and then added to the front end of the current scope chain, where information about the wrong object Error , such as Name,message, is stored primarily in the variable object.

Block-level scopes

There is no block-level scope in JavaScript (ES5), and ES5 supports the same scope as the execution environment, mainly the function (local) scope, the global scope.
When declaring a variable, if you use a var keyword, the declared variable is added to the variable object in the current execution environment and, if no keyword is used var , is added to the global execution environment's variable object by default.

Whether it is a global scope or a local scope, the correct operation when declaring a variable is to use the var keyword to declare it.

Overview of garbage collection mechanisms

JavaScript supports an automated garbage collection mechanism, rather than requiring manual tracking of memory usage like c,c++, and the so-called automatic garbage collection mechanism is very simple, and that is, every once in a while, the periodic inspection program executes, Frees the memory that is not in use by the identifier it occupies, or automatically allocates the memory space that is needed during the execution of the program, so that the developer only has to focus on the business function code, without worrying too much about memory usage.

When we understand the general principle of the garbage collection mechanism, then how to determine whether an identifier, whose life cycle has ended, is the function core of garbage auto-recovery.

Mark Clear

Mainstream browser vendors, basically use "mark and sweep" to identify those variables can be recycled, those variables also have a reference relationship cannot be recycled.
The general idea is that when a variable enters the execution environment, it adds a flag bit for it to indicate that the variable entered the environment, and in principle never releases the variable into the environment, because the execution process enters the appropriate environment and is likely to be used. When a variable leaves the environment, it then leaves its flag in the left state.
There are many ways to record this type of sign, you can record when a variable enters the environment and when to leave the environment by flipping a bit, or you can use the map table to record the status information separately when entering and leaving.
When JS's garbage collection is running, it will tag all the variables stored in memory (in any way) and then it will remove the variable tags that have referential relationships in the global environment and in the execution environment, after which the tags (which can be considered exit tags) are considered ready to be deleted. The reason is that these variables are no longer required to be accessed.
Simply summed up, when the variable enters the environment, it is marked as 1, leaving the time to 0, and then JS garbage collection mechanism every time to scan, will be marked as 0 of the variable to release.
The code is used to represent the following:

var status = 1 //进入环境status = null //离开环境,或者为Null的时候,马上被垃圾回收机制回收。
Reference count

"Reference count (reference counting)". A reference count is actually a count tag on a value, and when we define a variable and assign it a reference type, the value of the reference type defaults to 1, and when the value is referenced by another variable, the number of references is added by 1. Conversely, when a variable that references this value refers to a different value, its number of references is reduced by 1. When the reference to this value is 0 o'clock, it means that the value has been and has not been referenced by other variables, and it is possible to release the memory it occupies.

A very serious problem with reference counting is the "circular reference", where A's value has a reference to the B value, and the B value also has a reference to the A value, and a circular reference occurs.

function problem(){    var ObjectA = new Object();    var ObjectB = new Object();    ObjectA.A = ObjectB;    ObjectB.B = ObjectA;}

In this case, the variables objecta and OBJECTB are referenced two times, the first time the variables are declared and assigned, and the second time they are cross-referenced by their respective properties. So at this point the values of these two objects are referred to 2, if there is no problem in the policy of markup cleanup, but in the way of reference counting, objecta and OBJECTB will exist after the function is finished, because they will never be 0 references. If this function is repeated multiple times, it will result in more memory space being reclaimed.

Browsers with a "reference count" approach are very old, mostly Netspace Navigator 3.0 and before, so there's no need to worry too much, but it's still very necessary to understand, because before IE9, the native object of JavaScript was marked clear. , but for non-native objects, such as the garbage collection mechanism such as bom,dom, is still a reference counting policy, so if you need to be compatible with IE9 the following versions of the browser, when operating non-native objects, there may be a circular reference problem.

Case code:

var element = document.getElementById('element');var myObject = new Object();myObject.element = element;element.hostObject = myObject;

In this case, we'd better write the code to avoid, if it is difficult to avoid, then after the completion of the program to remember to manually release.

myObject.element = null;element.hostObject = null;
Performance issues

We know that the garbage collection mechanism is running periodically, so determining the time interval for GC is a very important issue.
Before IE7, the recovery mechanism of IE is based on the allocation of memory, the specific point is 256 variables, 4,096 objects (or arrays) literal and array element (slot) or 64KB string, to achieve any of the above critical value, the garbage collector will run. The problem with this approach is that if a script has a lot of variables, the script is likely to keep so many variables throughout its life cycle. As a result, the garbage collector has to be executed frequently, which affects the normal execution of the program.
After IE7, Microsoft has rewritten the Internet Explorer garbage collection mechanism, the variable allocation, the literal and/or the threshold value of the array element triggered by the garbage collector is adjusted to dynamic correction, the critical values are the same as those of the IE6 and previous versions, and if the garbage collection routine reclaims less than 15% memory allocations, the variables, The critical value of the literal and/or array elements is doubled, and if the routine reclaims 85% of the memory allocations, then the thresholds are reset to the default values.

There is another way to improve the performance of execution in everyday coding, which is to assign a value to a variable that is no longer used for null manual release. In general, this approach is often used for global variables, because local variables are cleaned up by the garbage collection mechanism themselves.

function doSomething() {    var obj = new Object();    return obj.name = 'csutom';}var global_var = doSomething();//...global_var = null; //当不用的时候最好记得手动释放

JavaScript Advanced Programming Chapter Fourth: 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.