Javascript object-oriented support (4)

Source: Internet
Author: User

========================================================== ==========================================================
Qomolangma openproject v0.9

Category: rich Web Client
Key words: JS Oop, JS framwork, rich Web Client, Ria, Web component,
Dom, dthml, CSS, JavaScript, JScript

Project Initiation: aimingoo (aim@263.net)
Project Team: aimingoo, Leon (pfzhou@gmail.com)
Contributor: Jingyu (zjy@cnpack.org)
========================================================== ==========================================================

VIII. Javascript object-oriented support
~~~~~~~~~~~~~~~~~~
(Continued)

3. structure, structure, and prototype Problems
--------
We already know that an object needs to be generated through the constructor function. Remember the following points:
-The constructor is a common function.
-The prototype is an object instance.
-The constructor has the original type attribute and the object instance does not
-(If the model is inherited normally, the constructor attribute of the object instance points to the constructor.
-From Article 3 and Article 4: obj. constructor. Prototype points to the original object
Type

Well, let's analyze an example to illustrate the JavaScript "inherited prototype" statement
And the construction process.
//---------------------------------------------------------
// Understand examples of prototype, construction, and inheritance
//---------------------------------------------------------
Function myobject (){
This. V1 = 'abc ';
}

Function myobject2 (){
This. v2 = 'def ';
}
Myobject2.prototype = new myobject ();

VaR obj1 = new myobject ();
VaR obj2 = new myobject2 ();

1) formal code for the new () keyword
------
Let's take a look at the new keyword in the "obj1 = new myobject ()" line of code.

The new keyword is used to generate a new instance. (I am used to calling reserved words key .)
Word. In addition, the new keyword in Javascript is also an operator), the default attribute of this instance
(At least) a reference to the prototype of the constructor function (in ECMA Javascript
In the specification, the property name of the object is defined as _ PROTO __).

Each function, whether or not used as a constructor, has a unique prototype ).
For JavaScript "built-in object constructor", it points to an internal prototype. Lack of time-saving Javascript
Create an "null initial object instance (not null)" and point the prototype reference to it. However, if you send a letter
The prototype of the number is assigned a new object, so the new object instance will have a reference to it.

Next, the constructor calls myobject () to complete initialization. -- Note: This is just "initial
".

To clearly explain this process, I use code to formally describe this process:
//---------------------------------------------------------
// Formal code for the new () keyword
//---------------------------------------------------------
Function new (afunction ){
// Basic object instance
VaR _ this = {};

// Prototype reference
VaR _ PROTO = afunction. Prototype;

/* If compat ECMA script
_ This. _ PROTO _ = _ PROTO;
*/

// Add (internal) getter for the attribute in the access prototype
_ This. _ js_getattributes = function (name ){
If (_ existattribute. Call (this, name ))
Return this [name]
Else if (_ js_lookupproperty.call (_ PROTO, name ))
Retrun obj_get_attributes.call (_ PROTO, name)
Else
Return undefined;
}

// Add (internal) setter for the attribute in the access prototype
_ This. _ js_getattributes = function (name, value ){
If (_ existattribute. Call (this, name ))
This [name] = Value
Else if (obj_get_attributes.call (_ PROTO, name )! = Value ){
This [name] = value // create a new member of the current instance
}
}

// Call the constructor to complete initialization (if any) and pass in The args
Afunction. Call (_ this );

// Return object
Return _ this;
}

So we can see the following two points:
-The Constructor (afunction) only initializes the incoming this instance, while
It is not used to construct an object instance.
-The construction process actually occurs inside the new () keyword/operator.

Moreover, the constructor itself does not need to operate prototype or return this.

2) prototype chain maintained by user code
------
Next we will discuss the prototype chain and construction process in depth. This is:
-The prototype chain is created by the user code. The new () keyword does not help maintain the prototype chain.

Taking Delphi code as an example, we can use this code when declaring an inheritance relationship:
//---------------------------------------------------------
// "Class" type declaration used in Delphi
//---------------------------------------------------------
Type
Tanimal = Class (tobject); // animal
Tmammal = Class (tanimal); // mammal
Tcanine = Class (tmammal); // mammals in the dog family
Tdog = Class (tcanine); // dog

At this time, the Delphi compiler will maintain an inherited link linked list through the compilation technology. We can
Run the following code to query the linked list:
//---------------------------------------------------------
// Key code for using the link list in Delphi
//---------------------------------------------------------
Function isanimal (OBJ: tobject): Boolean;
Begin
Result: = obj is tanimal;
End;

VaR
Dog: = tdog;

//...
Dog: = tdog. Create ();
Writeln (isanimal (DOG ));

As you can see, in Delphi user code, you do not need to directly protect the linked list of inheritance relationships. This is because
Delphi is a strongly typed language. When the class () keyword is used to declare the type, the Delphi compiler
This inheritance relation chain has been constructed for the user. -- Note that this process is declaration, not execution.
Code.

In JavaScript, if you need to know whether the object is a subclass object of a base class
You need to manually maintain a linked list (similar to the Delphi example. Of course, this linked list is not
It is called the type inheritance tree and the prototype linked list of an object ". -- In JS, there is no "class" type.

Refer to the previous JS and Delphi code. A similar example is as follows:
//---------------------------------------------------------
// Key code of "prototype linked list" in JS
//---------------------------------------------------------
// 1. Constructor
Function animal (){};
Function mammal (){};
Function canine (){};
Function dog (){};

// 2. Prototype linked list
Mammal. Prototype = new animal ();
Canine. Prototype = new mammal ();
Dog. Prototype = new canine ();

// 3. Example Function
Function isanimal (OBJ ){
Return OBJ instanceof animal;
}

VaR
Dog = new dog ();
Document. writeln (isanimal (DOG ));

As you can see, in the JS user code, the "Prototype linked list" construction method is a line of code:
"Constructor function of current class". Prototype = "instance of direct parent class"

This is different from a language like Delphi: the essence of maintaining the prototype chain is to execute code rather than declaration.

So what is the significance of "execution rather than Declaration?

Javascript compilation may occur. This process mainly deals with "syntax errors" and "Language
Statement and Conditional compilation command ". Here, the "syntax Declaration" mainly deals with letters
Number statement. -- This is also one of the reasons why I say "functions are the first class, but objects are not.

For example:
//---------------------------------------------------------
// Relationship between function declaration and execution statement (Firefox compatibility)
//---------------------------------------------------------
// 1. Output 1234
Test Foo (1234 );

// 2. Try to output obj1
// 3. Try to output obj2
Testfoo (obj1 );
Try {
Testfoo (obj2 );
}
Catch (e ){
Document. writeln ('exception: ', E. Description,' <br> ');
}

// Declare testfoo ()
Function testfoo (v ){
Document. writeln (v, '<br> ');
}

// Declare an object
VaR obj1 = {};
Obj2 = {
Tostring: function () {return 'Hi, object .'}
}

// 4. Output obj1
// 5. Output obj2
Testfoo (obj1 );
Testfoo (obj2 );

The result of this sample code execution in the JS environment is:
------------------------------------
1234
Undefined
Exception: 'obj1' undefined
[Object object]
Hi, OBJ
------------------------------------
The problem is that testfoo () is executed before it is declared, and "directly declared" is also used.
Object variables defined in the form, but cannot be referenced before declaration. -- Example 2 and 3
Input is incorrect.

Functions can be referenced before declaration, while other types of values must be declared before use.
This indicates that "Declaration" and "execution period reference" are two processes in JavaScript.

In addition, we can also find that when "Var" is used for declaration, the compiler will first confirm that this variable exists.
Yes, but the variable value will be "undefined ". -- Therefore, "testfoo (obj1)" will not be sent
An exception occurs. However, normal output is only available when the value assignment statement about obj1 is executed.
Compare the output differences between the second, third, fourth, and fifth rows.

Because JavaScript maintains the prototype chain as "executed" rather than "declared", this shows that "prototype"
The chain is maintained by user code, rather than by the compiler.

From this inference, let's look at the example below:
//---------------------------------------------------------
// Example: Incorrect prototype chain
//---------------------------------------------------------
// 1. Constructor
Function animal () {}; // animal
Function mammal () {}; // mammal
Function canine () {}; // mammal in the dog family

// 2. Construct the prototype chain
VaR instance = new mammal ();
Mammal. Prototype = new animal ();
Canine. Prototype = instance;

// 3. Test output
VaR OBJ = new canine ();
Document. writeln (OBJ instanceof animal );

This output results show us the result of a wrong prototype chain, "dog's breastfeeding
Things are not an animal ".

The root cause is that several lines of code under "2. Build prototype chain" are interpreted and executed, rather
Function is "declared" and understood during compilation. The solution to the problem is to modify the three
Line of code to make its "Execution Process" logical:
//---------------------------------------------------------
// Correction Code of the previous example (Part)
//---------------------------------------------------------
// 2. Construct the prototype chain
Mammal. Prototype = new animal ();
VaR instance = new mammal ();
Canine. Prototype = instance;

3) How the prototype instance is used in the construction process
------
Take Delphi as an example. During the construction process, Delphi will first create
"Empty objects", assign values to attributes one by one, and call methods and triggers in the constructor.
.

The implicit construction process in the new () keyword in Javascript is not exactly the same as that in Delphi. However
The behavior in the constructor function is similar to the above:
//---------------------------------------------------------
// Construction process in JS (form code)
//---------------------------------------------------------
Function myobject2 (){
This. Prop = 3;
This. method = a_method_function;

If (you_want ){
This. Method ();
This. fire_oncreate ();
}
}
Myobject2.prototype = new myobject (); // declaration of myobject ()

VaR OBJ = new myobject2 ();

If a single class is used as the reference object, JavaScript can have
The same rich behavior. However, since the construction process in Delphi is "dynamic", in fact
Delphi also calls the construction process of the parent class (myobject) and triggers the oncreate () event of the parent class.

JavaScript does not have this feature. The construction process of the parent class only occurs in prototype
Attribute. Then, no matter how many new myobject2 () occurs,
The constructor myobject () is not used. -- This also means:
-During the construction process, the prototype object is generated at a time. The new object only holds the reference of this prototype instance.
(Using the "Write replication" mechanism to access its attributes), instead of calling the prototype constructor.

Because the constructor of the parent class is no longer called, some features in Delphi cannot be implemented in JavaScript.
This mainly affects some events and behaviors in the construction phase. -- Some "objects are being constructed"
The code is written to the constructor of the parent class. Because no matter how many times the subclass constructs, the root of this object construction process
This will not activate the code in the parent class constructor.

In JavaScript, attribute access is dynamic, because the object access parent class attributes depend on the prototype linked list to construct
The process is static and does not access the constructor of the parent class. In some compilation languages such as Delphi
The access to attributes is static, while the object construction process dynamically calls the constructor of the parent class.
So again, you can see this line in the form code of the new () Keyword:
//---------------------------------------------------------
// Formal code for the new () keyword
//---------------------------------------------------------
Function new (afunction ){
// Prototype reference
VaR _ PROTO = afunction. Prototype;

//...
}

In this process, JavaScript is "Get A prototype_ref", while Delphi and other languages are
Is "inherited create ()".

(This section is not complete ...)

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.