On the language characteristic analysis of JavaScript _javascript skills

Source: Internet
Author: User
Tags logical operators

Objective
In JavaScript, scopes, contexts, closures, functions are the essence of the essence. For the primary jser, it is a prerequisite for advanced. For the front siege, the only way to write elegant code is to calm down and understand the essence.

This article aims to summarize the important knowledge that is easy to forget and will not speak the basic concept. If you are unfamiliar with the basics, go ahead and turn to the JavaScript Authority Guide.


Expression of language attribute function

First look at the code snippet:

Copy Code code as follows:

[JavaScript] View plaincopyprint?
var f = function foo () {
Return typeof Foo; Foo is valid within the internal scope
};
Foo is not visible for external use
typeof Foo; "Undefined"
f (); "Function"
var f = function foo () {
Return typeof Foo; Foo is valid within the internal scope
};
Foo is not visible for external use
typeof Foo; "Undefined"
f (); "Function"

One thing to say here is that Foo in a function expression can only be referenced inside a function and cannot be referenced outside.


Json

Many JavaScript developers mistakenly refer to JavaScript object literals (object literals) as JSON objects (JSON Objects). JSON is designed to describe the data Interchange format, and it has its own syntax, which is a subset of JavaScript.

{"prop": "Val"} such a declaration might be a JavaScript object literal or a JSON string, depending on what context uses it. If used in a string context (enclosed in either single or double quotes, or read from a text file), it is a JSON string, which is the object literal if it is used in an object literal context.

Copy Code code as follows:

[JavaScript] View plaincopyprint?
This is a JSON string
var foo = ' {prop ': ' Val '} ';
This is the literal amount of the object
var bar = {"prop": "Val"};
This is a JSON string
var foo = ' {prop ': ' Val '} ';
This is the literal amount of the object
var bar = {"prop": "Val"};

It is also important to know that Json.parse is used to deserialize the JSON string into an object, and json.stringify is used to serialize the object into a JSON string. The old version of the browser does not support this object, but you can do the same with Json2.js.


Prototype

Copy Code code as follows:

function Animal () {
// ...
}
function Cat () {
// ...
}
Cat.prototype = new Animal ();//This way inherits from the constructor.
Cat.prototype = animal.prototype;//This way does not inherit from constructors.
Another important detail to note is the need to maintain their own prototype chain, the Novice will always forget this!
Cat.prototype.constructor = cat;

If we completely change the prototype property of the function (by assigning a new object), the reference to the original constructor is lost because the object we created does not include the constructor attribute:

Copy Code code as follows:

function A () {}
A.prototype = {
X:10
};
var a = new A ();
alert (a.x); 10
Alert (A.constructor = = a); false!

Let's take a look at MDN's explanation of constructor: Prototype:returns a reference to the Object function that created the instance. This, a prototype reference to a function needs to be manually restored:

Copy Code code as follows:

function A () {}
A.prototype = {
CONSTRUCTOR:A,
X:10
};
var a = new A ();
alert (a.x); 10
Alert (A.constructor = = a); True

However, the commit prototype property does not affect the prototype of the object that has been created (only when the prototype property of the constructor changes), meaning that the newly created object has a new prototype. Just create an object or refer to the original old prototype (this prototype can no longer be modified).

Copy Code code as follows:

function A () {}
a.prototype.x = 10;
var a = new A ();
alert (a.x); 10
A.prototype = {
CONSTRUCTOR:A,
X:20
Y:30
};
Object A is a value obtained from the Prototype of crude oil by an implicit [[Prototype]] Reference
alert (a.x); 10
Alert (A.Y)//undefined
var B = new A ();
But the new object is the value obtained from the newly-prototyped
alert (b.x); 20
Alert (B.Y)//30

Therefore, "Dynamic modification of the prototype will affect all objects will have a new prototype" is wrong, the new prototype is only after the prototype modification of the new created object to take effect. The main rule here is that the object's prototype is created when the object is created, and cannot be modified to a new object after that, and if you still refer to the same object, you can use the explicit prototype reference of the constructor, and after the object is created, you can only add or modify the properties of the stereotype.

A variable object in the execution context of a function, VO (variable object) is not directly accessible, at which point the active object (activation object) plays the role of Vo. The active object is created at the moment of entering the function context, and it is initialized by the arguments property of the function. The value of the arguments property is the arguments object:


Copy Code code as follows:

function foo (x, y, z) {
Number of function arguments declared arguments (x, y, z)
alert (foo.length); 3
Number of arguments actually passed in (only X, y)
alert (arguments.length); 2
The callee of the parameter is the function itself
Alert (Arguments.callee = = foo); True
}

When entering the execution context (before code execution), VO already contains the following attributes: 1. All parameters of the function (if we are in the function execution context);

• All function declarations (functiondeclaration, FD);
• All variable declarations (Var, variabledeclaration);
Another classic example:

Copy Code code as follows:

alert (x); function
var x = 10;
alert (x); 10
x = 20;
function X () {};
alert (x); 20

According to the canonical function declaration, it is filled in when the context is entered; There is also a variable declaration "x" when entering the context, so as we said above, variable declarations are followed in order with function declarations and formal parameter declarations, and in this entry-context phase, variable declarations do not interfere with functions or formal parameter declarations that already exist in VO. Variables have an attribute: {dontdelete}, which means that the variable property cannot be deleted directly with the delete operator, as opposed to a simple property.

Copy Code code as follows:

A = 10;
alert (WINDOW.A); 10
Alert (delete a); True
alert (WINDOW.A); Undefined
var B = 20;
alert (WINDOW.B); 20
Alert (delete b); False
alert (WINDOW.B); Still 20. B is Variable,not property!
var a = 10; Variables in the global context
(function () {
var B = 20; Local variables in a function context
})();
alert (a); 10
alert (b); global variable "B" has no declaration.

This is in a function context, this is provided by the caller and is determined by the way the function is invoked. If the left side of the call bracket () is a value of a reference type, this is set to the base object (base objects) that refers to the type value, and in other cases (any other property that differs from the reference type), this value is null. However, there is no actual case where this value is NULL, because its value is implicitly converted to the global object when the value of this is null.

Copy Code code as follows:

(function () {
alert (this); Null => Global
}) (); <span style= "line-height:25.2px; Font-family:helvetica, Tahoma, Arial, Sans-serif; Font-size:14px "> </SPAN>

In this example, we have a function object that is not a reference type object (it is not a identifier, nor is it a property accessor), and, accordingly, the this value is eventually set to the global object.

Copy Code code as follows:

var foo = {
Bar:function () {
alert (this);
}
};
Foo.bar (); Reference, OK => foo
(Foo.bar) (); Reference, OK => foo
(Foo.bar = foo.bar) (); Global
(False | | foo.bar) (); Global
(Foo.bar, Foo.bar) (); Global

The problem is that the next three calls, after applying a certain operation, are not in the reference type at the left of the call bracket.

• The first example is obviously ——— obvious reference type, and as a result, this is the base object, Foo.

• In the second example, the group operator does not apply, and think about the method mentioned above that obtains the true value of an object from a reference type, such as GetValue. Accordingly, in the return of the group operation ——— we are still a reference type. This is why this value is again set to the base object, that is, Foo.

• In the third example, unlike the group operators, the assignment operator invokes the GetValue method. The result returned is a function object (but not a reference type), which means that this setting is null and the result is a global object.

• The fourth and fifth are the same--the comma and logical operators (or) call the GetValue method, and correspondingly, we lose the reference and get the function. and set to global again.

As we know, local variables, internal functions, and formal parameters are stored in the activation object of the given function.

Copy Code code as follows:

function foo () {
function Bar () {
alert (this); Global
}
Bar (); The same as Ao.bar ()
}

The active object is always returned as this, and the value is null--(that is, the Ao.bar () of the pseudo code is equivalent to Null.bar ()). Here we go back to the example described above, this is set as a global object.


Scope chain

The scope property of a function created by a functional constructor is always a unique global object.

An important exception relates to functions created by function constructors.

Copy Code code as follows:

var x = 10;
function foo () {
var y = 20;
function Barfd () {//Functions Declaration
alert (x);
alert (y);
}
var barfn = Function (' alert (x); alert (y); ');
BARFD (); 10, 20
BARFN (); "Y" is not defined
}
Foo ();

And also:

Copy Code code as follows:

var x = ten, y = 10;
With ({x:20}) {
var x =, y = 30;
Here The X = 30 covers x = 20;
alert (x); 30
alert (y); 30
}
alert (x); 10
alert (y); 30

What happens when you enter the context? The identifier "x" and "Y" have been added to the variable object. In addition, make the following modifications in the code run phase:

x = ten, y = 10;
• Object {x:20} is added to the front of the scope;
• Inside with, the Var declaration was encountered, and of course nothing was created because all the variables were parsed and added when the context was entered;
In the second step, only the variable "x" is modified, in fact the "X" in the object is now parsed and added to the front end of the scope chain, "X" is 20 and becomes 30;
• also has the variable object "Y" the modification, after parsing its value also to change from 10 to 30;
• Furthermore, after the with declaration is completed, its specific object is removed from the scope chain (the changed variable "x"--30 is also removed from that object), that is, the structure of the scope chain is restored to the previous state where the with is strengthened.
• In the last two alert, the "X" of the current variable object remains the same, and the value of "Y" is now equal to 30, and changes have occurred in the with declaration run.
Function

Questions about parentheses

Let's look at the question: ' Why do we have to surround it with parentheses in an immediate call after a function is created? ' The answer is this: that's the limit of the expression sentence.

By standard, an expression statement cannot start with a curly brace {because it is difficult to distinguish it from a block of code, and he cannot start with a function keyword because it is difficult to distinguish it from a function declaration. That is, so if we define a function that executes immediately, it is invoked as follows immediately after its creation:

Copy Code code as follows:

function () {
...
}();
Even if there is a name
function foo () {
...
}();

We use the function declaration, the above 2 definitions, the interpreter in the interpretation of the error will be, but there may be several reasons. If you define it in the global code (that is, the program level), the interpreter will consider it as a function declaration because he starts with the functions keyword, and in the first case we get the SyntaxError error because the function declaration has no name (we mentioned earlier that the function declaration must have a name). In the second example, we have a function declaration called Foo that is normally created, but we still get a syntax error--there is no group operator error for any of the expressions. After the function declaration he is really a grouping operator, not a function call using parentheses. So if we declare the following code:

Copy Code code as follows:

"Foo" is a function declaration that is created when the context is entered
Alert (foo); Function
function foo (x) {
alert (x);
} (1); This is just a grouping operator, not a function call!
Foo (10); This is a real function call, and the result is 10.

The simplest way to create an expression is to use the grouping operator bracket, which is always an expression, so the interpreter does not appear ambiguous when interpreting it. This function is created in the code execution phase and executed immediately, and then automatically destroyed (if not referenced)

Copy Code code as follows:

(function foo (x) {
alert (x);
}) (1); This is the call, not the grouping operator.

The code above is what we call an expression enclosed in parentheses and then passed (1). Note that the surrounding parentheses are not necessary because the function is already in the position of the expression, and the parser knows that it handles the FE that should be created at the function execution stage, so that the function is called immediately after the function is created.

Copy Code code as follows:

var foo = {
Bar:function (x) {
return x 2!= 0? ' Yes ': ' No ';
} (1)
};
alert (foo.bar); ' Yes '

As we can see, Foo.bar is a string rather than a function, where the function is used only to initialize the property based on the condition parameter-it is created and called immediately.


1. Therefore, the complete answer to the question "about parentheses" is as follows:
2. When the function is not in the position of the expression, the grouping operator parenthesis is required--that is, manually converting the function to FE.
3. If the parser knows that it is dealing with Fe, there is no need to use parentheses.
Free variable:

Copy Code code as follows:

function Testfn () {
var Localvar = 10;//for the INNERFN function, Localvar is a free variable.
function Innerfn (innerparam) {
Alert (Innerparam + Localvar);
}
return INNERFN;
}

Static scope of closures:

Copy Code code as follows:

var z = 10;
function foo () {
alert (z);
}
Foo (); 10– when using static and dynamic scopes
(function () {
var z = 20;
Foo (); 10– using static scopes, 20– using dynamic scopes
})();
The same is the case for Foo as a parameter
(function (Funarg) {
var z = 30;
Funarg (); 10– static scopes, 30– dynamic scopes
}) (foo);

Theory: Because of the scope chain, all functions are closed (regardless of function type: Anonymous functions, FE,NFE,FD are closures). From a practical standpoint: The following function is considered a closure: * Even if the context in which it was created has been destroyed, it still exists (for example, the intrinsic function is returned from the parent function)

* Reference the free variable in the code

At last:
ECMAScript is an object-oriented language that supports prototype-based delegate inheritance.

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.