The object you don't know in JavaScript (ii)--function

Source: Internet
Author: User

The previous article (object (a) You don't know in JavaScript) says that object objects have a large number of intrinsic properties, most of which are related to the operation of external properties. Finally left a suspense, that is, Boolean, Date, number, String, function, etc. have more internal properties, and what are they?

These internal properties cannot be as word as the intrinsic properties of an object, because they each have their own usefulness and characteristics. One of the core parts is naturally the most special object, the function object. Let's start with a simple first:

  1. [[Primitivevalue]]: The type of the value is the underlying data type. So all wrapper classes, such as Boolean, number, and string, have this intrinsic property, where date is also used to store timestamps.
  2. [[Construct]]: The type of the value is a method. Pass in the parameter list and return object. The function object is unique, and is the internal property that is called when using new Func (). So the method of owning this property can also be called a constructor. Note the constructor property under the prototype object that distinguishes the constructor.
  3. [[Call]]: The type of the value is a method. Passes in the parameter list, returning any data type. The function object is unique, and is the internal property that is called when using Func ().
  4. [[Hasinstance]]: The type of the value is a method. Pass in any value and return a Boolean. The prototype of this function is found on the prototype chain that detects this parameter, that is, whether an object in the detection parameter and its prototype is created when this function is used as a constructor.
  5. [[Scope]: function object specific, whenever the function is executed, use this internal property to add a new scope chain to the new execution Environment .
  6. [[Formalparameters]]: formal parameter list. function objects are unique.
  7. [[Code]]: JS code. function objects are unique.
  8. [[Targetfunction]]: The following
  9. [[Boundthis]]: The following
  10. [[Boundarguments]]: The following
    The above three function-specific intrinsic properties created for Function.prototype.bind.
    var arr1 = [1, 4, 5],    = [2, 3]; var func = Array.prototype.splice.bind (arr1, 1, 0//[1, 2, 3, 4, 5]
    In the example, Func is a function created through bind, with its internal properties [[[Targetfunction]] corresponding to array.prototype.splice,[[boundthis]] corresponding to arr1,[[boundarguments]] corresponds to 1 A list of 0 components.

The properties listed above may seem to be understandable at first glance, but it is very abstract to think about the scope and execution environment of the red, and we are now going to take a complete look at the concepts.

The first concept introduced is executable code. ES provides three executable codes: Global code, eval code, and function code. When executing to these three types of code, the interpreter creates and enters the new execution environment, and when the code is finished, the interpreter exits and destroys the current execution environment and goes back to the previous execution environment.

So far the execution environment is an abstract concept, what is the implementation of the environment? First, it has three elements: the lexical environment, the variable environment, the this binding. This binding we are more familiar with, that lexical environment and variable environment is what to use it? Simple and less rigorous, the lexical environment is the scope chain, used to take the value of the variable, and the variable environment temporarily understood as the current scope bar, used to assign the value of the variable. Let's raise a chestnut:

varA = 0;functiontest0 () {console.log (a);//0Console.log (WINDOW.A);//0}functiontest1 () {a= 1; Console.log (a); //1Console.log (WINDOW.A);//1}functiontest2 () {varA = 2; Console.log (a); //2Console.log (WINDOW.A);//1}test0 (); Test1 (); Test2 ();

There are 4 execution environments involved: the global execution Environment, the test0-2 execution environment.

After entering the execution environment of the test0, to print out a, the current scope does not define the variable, so follow the scope chain to find a global execution environment defined in a, so print out 0, I believe there is no problem.

After entering the execution environment of test1, the execution environment of TEST0 has been exited. When a value is given to a, someone might immediately think, assign a value? OK, the variable environment is used for the current scope, so a should be 1,window.a or 0, but the result is not. We take a = 1 apart, the first is to take a variable, the current scope does not have this variable , so a This variable points to a global execution environment, then the assignment, 1 naturally assigned to a in the global execution environment. So how do you get this variable in the current scope? Statement ! That is, var a = 2 in test2, we also take apart to see, first declare a, so in the current scope is bound to a variable, that is, add a in the variable environment, and then take a variable, from the scope chain in the current scope to find a, and finally assign 2 to a.

So let's standardize the definition above: the lexical environment is used to find variables that can be understood as scope chains . The variable environment, which can no longer be understood as a scope, is an object used to store the binding information between the current execution environment and the variables . Note that a key is hidden here: The variables are looked up in scope, and the declared variables are stored in the execution environment. Don't understand it's okay, keep going.

The careful words in the example may detect something wrong: Why can a variable declared in the global Execution environment be accessed through a global object, and can I access the a declared in Test2 by test2.a?

Of course it's not. because scopes fall into two categories: one is declarative and the other is object-like . The scope of function generation is declarative, and the scope of the global execution environment is object-style. All variables declared in the object scope can be accessed through the properties of this object, while the declarative can define variables that cannot be modified, and you will try to modify the arguments in the function in strict mode.

I believe it's basically a mess here. Let me tidy up a few questions: what is the relationship between the scope and the execution environment? Do declarative and object scopes only correspond to function and global?

First, a single execution environment can produce multiple scopes, but there is one underlying scope. And then how do the other scopes spawn? The scope of the declarative is also generated, that is, the catch statement, we can access the Error object through E in the statement of the catch (E) {}, that is, a declarative scope is generated, and the variable e is added to the scope. The scope of the object type is also generated in a way, which is the WITH statement.

varA ={name:' Tarol '},name= ' Okal '; with(a) {Console.log (name); //TarolConsole.log (Window.name);//Okalname = ' Ctarol ';  Console.log (name); //CtarolConsole.log (Window.name);//Okal  varAge = 18;} Console.log (A.age); //undefinedConsole.log (Window.age);// -

In the example, after entering the WITH statement, a new object scope is generated and added to the head of the scope chain, so access to the variable name in the statement is the value of A.name, and the assignment to the variable name is also an assignment to the A.name value. The difficulty after var = 18, The age attribute is not assigned to a, but is assigned to window. Just like the boy a looked at the girl age, agreed to also booked a marriage, the last girl married to A's boss window (how a kind of Caocao and Guan Yu's Sense of sight). The reason is that the WITH statement modifies the lexical context of the execution environment, so the rules of the access variable are changed, but the variable environment is not modified, so the declared variables are all given to the underlying scope in the global execution environment (a: How can I forget this? )。

In addition, the var age = 18 Var is removed, the result is the same. Because of the time to marry variables, matchmaker find AH find, find the last scope has not found, so stopped there, suddenly saw a value to come, also lazy to change place, on the spot in this scope to dress up as a variable. So removing var a = 0 from the previous example does not affect the result of test1 ().

  Watch out! Attention! Attention! Assigning values to undefined variables throughout the scope chain, this variable binds to the end of the scope and assigns values to undefined attributes in the prototype chain, which is tied to the head of the prototype chain, which is the current object. give two chestnuts at a time:

var a = {}; function Test () {  with(a) {    =;   //  +

var a = {},    ==//undefined

Well, say so much, go back to the previous internal properties [[Scope]]. It is created at the creation of a function, the value is the scope chain when it is created, and is used when executing a function to generate a scope chain in the new execution environment.

  Note that this [[Scope]] is the creation function that is generated!

Note that this [[Scope]] is the creation function that is generated!

Note that this [[Scope]] is the creation function that is generated! So no matter where the function is executed, the scope chain is the same.

Give a chestnut:

varA ={age:18},age= 19; with(a) {varTest0 =function() {Console.log (age);  }; functiontest1 () {Console.log (age); } test0 (); // -Test1 ();// +}!function() {  varAge = 20; functiontest2 () {Console.log (age); } test0 (); // -Test1 ();// +Test2 ();// -} () test0 (); // -Test1 ();// +

It is important to note that when you create a new function in the WITH statement, if you want to insert a in the scope chain of this function, you want to use test0 declaratively instead of test1. As for why? It is a timing problem for variable declarations and function declarations, and after entering the execution environment, all the variable declarations and function declarations are traversed, and the function objects are generated, but the variables are not assigned values. This is also why JS in the function can be called after the declaration, because you casually write where, one into the execution environment on the function is generated. While the Test1 function is generated without a run to the WITH statement, [[Scope]] is naturally the underlying scope chain of the global execution environment. Test0 begins by declaring only a variable of undefined to be assigned to the WITH statement, so a is added to the function's [[Scope]].

Written in a disorderly, and for the sake of understanding, and did not standardize some concepts, such as environment records into a scope, Lexical environments into a scope chain. Later, the next (if any) of this series will be the internal properties of the RegExp type and the internal properties of the arguments.

The object you don't know in JavaScript (ii)--function article

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.