Reprint: JavaScript Scope principle

Source: Internet
Author: User

First look at an example:

  1. var name = ' laruence ';
  2. function echo() {
  3. Alert(name);
  4. var name = ' Eve ';
  5. Alert(name);
  6. Alert(age);
  7. }
  8. Echo();

What is the result of the operation?

The above question, I believe there will be a lot of people will think is:

    1. Laruence
    2. Eve
    3. [Script ERROR]

The second alert is ' Eve ' because it will be assumed that in Echo, the first alert will take the value of the global variable name and the second value is overwritten by the local variable name. The Age property is undefined, so the script will go wrong.

But in fact, the result of the operation should be:

    1. Undefined
    2. Eve
    3. [Script ERROR]

Why is it?

The scope chain of JavaScript

First let's take a look at the scope of Javasript (JS, which does not exactly represent JScript): The JS authoritative guide has a very incisive description: "The functions in JavaScript run in their defined scopes, not in the scopes they are executed in."

For the next knowledge, you can understand, I would remind you, in JS: "Everything is an object, function is also."

In JS, the concept of scope is similar to other languages, and each time a function is called, it enters a scope within a function, and when returned from the function, returns the scope before the call.

The syntax style of JS is similar to C + +, but the scope implementation is different from that of C + +, not by "stack", but by using a list, as described in ECMA262:
The scope of any execution context moment is implemented by the scope chain (scope chain, described later).
When a function is defined, the scope chain that defines the moment is linked to the [scope] property of the function object.
When a function object is called, an active object (that is, an object) is created, and then, for each function's formal parameter, it is named as the active object's named property, then the active object is the front-end of the scope chain (scope chain) at this time, and this function object's [[ Scope]] added to scope chain.

Look at an example:

    1.      var func = function{
    2.            var name = Laruence '
    3.            ...
    4.      }
    5.      func ();

When executing the FUNC definition statement, a [[scope]] property is created for the function object (internal property, only the JS engine can access, but several Firefox engines (SpiderMonkey and Rhino) provide a private property __parent__ to access it ), and link this [[scope]] property to the scope chain on which it is defined (described later), because Func is defined in the global environment, at this point [[scope]] simply points to the global Active object window active.

When the func is called, an active object is created (assumed to be aobj, created by the JS engine precompiled moment, described later), and the Arguments property is created, and then the object is added with two named properties Aobj.lps, Aobj.rps; For each local variable and function definition declared in this function, it is named as the Name property of the active object.

The call parameter is then assigned to the shape parameter, and the value is undefined for the missing invocation argument.

The active object is then taken as the front-end of the scope chain, and the Func's [[Scope]] property points to the top-level activity object that defines the func, adding to the scope chain.

With the above scope chain, in the event of identifier parsing, the property of each active object of the current scope chain list is queried backwards, and returned if the same name is found. Not found, that is, the identifier is not defined.

Notice that because the [scope] property of a function object is determined when a function is defined, not when it is called, as in the following example:

  1. var name = ' laruence ';
  2. function echo() {
  3. Alert(name);
  4. }
  5. function env() {
  6. var name = ' Eve ';
  7. echo();
  8. }
  9. env();

The operating result is:

    1. Laruence

Combining the above knowledge, let's take a look at the following example:

  1. Function Factory() {
  2. var name = ' laruence ';
  3. var intro = function(){
  4. Alert(' I am ' + name);
  5. }
  6. return intro;
  7. }
  8. function app(para){
  9. var name = para;
  10. var func = factory();
  11. func();
  12. }
  13. App(' Eve ');

When the app is called, scope chain is made up of the {Window Activity Object (Global)}->{app}.

When you first enter the app function body, the app's active object has a arguments property, and the two values are undefined properties: Name and Func. and a value of ' Eve ' attribute para;

The scope chain at this time is as follows:

  1. [[Scope chain]] = [
  2. {
  3. Para : ' Eve ',
  4. Name : undefined,
  5. Func : undefined,
  6. arguments : []
  7. }, {
  8. Window Call Object
  9. }
  10. ]

When calling into the factory function body, the factory scope chain at this time is:

    1. [[Scope chain]] = [
    2. {
    3. Name : undefined,
    4. Intor : undefined
    5. }, {
    6. Window Call Object
    7. }
    8. ]

Notice that the active object of the app is not included in the scope chain at this time.

When defining the intro function, the intro function's [[scope]] is:

    1. [[Scope chain]] = [
    2. {
    3. Name : ' laruence ',
    4. Intor : undefined
    5. }, {
    6. Window Call Object
    7. }
    8. ]

After returning from the factory function, the identifier parsing occurs when Intor is called in the app, and the Sope chain at this point is:

    1. [[scope chain]] = [
    2. {
    3.       intro Call Object
    4. } {
    5.      name ' laruence '
    6.      intor undefined
    7. }{
    8.      window Call Object
    9. }
    10. Span class= "Sh_symbol" >

Because the scope chain, the factory activity object is not included. Therefore, the result of the name identifier resolution should be the name attribute in the factory active object, which is ' laruence '.

So the result of the operation is:

    1. I am Laruence

Now everyone is running "javascript" functions in their defined scopes, not in the scopes they are executed in. This sentence, should have a comprehensive understanding of it?

Pre-compilation of JavaScript

As we all know, JS is a scripting language, JS execution process, is a translation of the process of execution.
So JS implementation, there is no similar to the process of compiling it?

First, let's look at an example:

  1. <script>
  2. Alert(typeof Eve); //function
  3. function Eve() {
  4. Alert(' I am laruence ');
  5. };
  6. </script>

Eh? Isn't eve supposed to be undefined at the time of alert? What is the type of Eve or function?

Well, yes, in JS, there is a pre-compilation process, JS in the execution of each JS code, will first deal with the VAR keyword and function definitions (function definitions and functional expressions).
As mentioned above, before invoking a function, an active object is created, then the local variable definition in the function is searched, and the function definition is defined, the variable name and function names are the same name properties of the active object, and for the local variable definition, the value of the variable is calculated when it is actually executed. This is simply a undefined.

The definition of a function is a place to note:

  1. <script>
  2. Alert(typeof Eve); //Result: function
  3. Alert(typeof Walle); //Result: undefined
  4. function Eve() { //functions definition
  5. Alert(' I am laruence ');
  6. };
  7. var Walle = function() { //functions expression
  8. }
  9. Alert(typeof Walle); //Result: function
  10. </script>

This is the difference between a function definition and a function expression, and for a function definition, the function definition is advanced. The function expression is evaluated during execution.

Speaking of which, by the way, a question:

    1. var name = ' laruence ';
    2. Age = +;

We all know that variables that are not defined with the VAR keyword are equivalent to global variables and are linked to what we have just learned:

When parsing an identifier for age, because it is a write operation, the identifier is not found when the global window activity object is found, and a value of undefined is returned on the basis of the window activity object.

In other words, age is defined in the top-level scope.

Now, maybe you notice what I just said: JS in the execution of each section of JS code .
Yes, let's take a look at the following example:

  1. <script>
  2. Alert(typeof Eve); //Result: undefined
  3. </script>
  4. <script>
  5. function Eve() {
  6. Alert(' I am laruence ');
  7. }
  8. </script>

Do you get it? That is, JS pre-compilation is a unit of processing units ...

Uncover the answer

Now let's go back to our first question:

When the Echo function is called, Echo's active object has been created by the precompiled process, at which point the active object of ECHO is:

    1. [Callobj] = {
    2. Name : undefined
    3. }

When the first alert occurs, an identifier resolution has occurred, and the name attribute is found in the Echo's active object, so the Name property completely obscures the Name property in the global active object.

Now you get it, don't you?

Http://www.laruence.com/2009/05/28/863.html

Reprint: JavaScript Scope principle

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.