In-depth analysis of the dojo object-oriented Mechanism

Source: Internet
Author: User
Tags hasownproperty

 

Dojo is a web control library based on the Javascript language. To understand the object-oriented mechanism of dojo, We can first review the basic object-oriented mechanism of JavaScript itself:

 

First, JavaScript uses functions to simulate object-oriented mechanisms, such:

Function func1 (){};

Func1 (); // function call

New func1 (); // instantiated object

In the preceding two methods, the internal this object of the function is also different.

 

In addition, there are two basic inheritance methods for JavaScript (of course, there are more complicated ones. Here we only list the two most basic methods)

1. Object impersonating method:

Function
Classa (scolor ){
This. Color = scolor;
This. xxx = xxx;

......
}

Function
Classb (scolor, name ){
This. newmethod = classa;

This. newmethod (scolor );
Delete this. newmethod;
......
}

Or :( classa is the same as above)

Function
Classb (scolor, sname ){
Classa. Call (this, scolor );
// Or apply



This. Name = sname;
This. sayname =
Function (){
Alert (this. Name );
};
}

 

 

 

2. prototype chain inheritance:

// Base class

Function classa ()
{}
Classa... = .....;
// Subclass
Function classb (){}

// Modify prototype to achieve the purpose of Inheritance
Classb. Prototype = new classa ();


// Define new attributes and Methods
Classb... = .....;

// Ensure constructor consistency (After prototype is modified, its constructor becomes classa, which should be classb)

Classb. Prototype. constructor =
Classb;

 

 

The above two methods have their own advantages and disadvantages: the object impersonating method is inefficient, and the constructor method must be used but supports multi-inheritance, while the prototype method is flexible but does not support multi-inheritance. The following hybrid method is used:

Function
Classa (scolor ){}
Classa... =... // set attributes

Function classb (){

Classa. Call (this, scolor); // attributes are inherited by the object impersonating method.


This. Name = sname;
}
Classb. Prototype = new classa (); // prototype
Inheritance Method


Classb. Prototype. sayname = function (){

Alert (this. Name );
}

 

 

Let's take a look at how dojo implements the Inheritance Mechanism:

The following is a simple example of declaring classes and using classes in Dojo. It can be seen that its core is a dojo. Declare function:

 

Let's take a look at the dojo. Declare function:

1> first, let's look at the first parameter: classname. You can see the following code:

......

// Add name if
Specified
If (classname ){
Proto. declaredclass = classname;

D. setobject (classname, ctor );

}

......

 

The Ctor is a function constructed in this method. It is actually the definition of the Declaration class. It is a function object and contains many members, including attribute definition and function definition, A detailed introduction to this will be discussed later. Here, we mainly use dojo. setobject to assign the constructed function object to a variable named classname, such as dijit. widgetset.

So here is equivalent to writing like this:

Ctor = function (){....};

Dijit. widgetset = ctor;

 

In addition, the proto here is the prototype of the ctor.

 

 

2> let's take a look at the third parameter: props. You can see the following code:(See the bold font description)

............

PROTO = {};

// Copy the content of a class definition object. For details, see the templatestring of dijit. Calendar above,
Value, buildrendering, and other attributes and methods.

Safemixin (PROTO, props );

//
Start to construct the ctor, that is, the definition of the constructor class. You can see that there are many attributes added by dojo.


T =! Chains |
! Chains. hasownproperty (cname );

// Singleconstructor/simpleconstructor/chainedconstructor
All

It is a function object, and its return value is also a function object. These returned function objects contain some default operations, including initialization, calling ctor, and its base class ctor, for details, refer to the definitions of the above three functions. We can see what the function simulating the dojo class did during initialization. It is worth studying, so that the length is not too long, I will not go into detail here for the time being.

Bases [0] = ctor = (chains & chains. constructor = "Manual ")?
Simpleconstructor (bases ):
(Bases. Length = 1?
Singleconstructor (props. constructor, T): chainedconstructor (bases,
T ));

// Add meta information to the constructor

// The ctor attribute here is critical, as mentioned above

The singleconstructor/simpleconstructor/chainedconstructor function is called. This is why the "class" of dojo. Declare automatically calls the constructor method during initialization (new operation !!!

Ctor. _ meta = {bases: bases, hidden: props, Chains: chains,
Parents:
Parents,Ctor: props. Constructor
};
Ctor. superclass =
Superclass & superclass. Prototype;
Ctor. Extend = extend;

 

// Here is a key operation. All defined attributes are taken as prototype attributes. Note that we will not talk about inheritance here, and it is not inherited here, separate it from the previous JavaScript inheritance

Ctor. Prototype =
PROTO;

// Because prototype is modified, a new value must be assigned to maintain the constructor consistency of prototype.

Proto. constructor = ctor;

//
Add commonly used methods in Dojo. Note: These methods are directly added to prototype!


Proto. getinherited =
Getinherited;
Proto. inherited = inherited;
Proto. isinstanceof =
Isinstanceof;

............

// Finally, assign the constructed Class Object ctor (essentially a function object) to the declared Class Name

Dojo. setobject (classname, ctor)

.............

 

So here we can actually know that the declare class in Dojo is essentially a function object. In fact, it is the following code:

Ctor =
Function (){};

Ctor. Prototype =
Props property definition .....

Class name variable {eval (classname)} = ctor;

 

 

3> let's take a look at the second parameter, which is related to the Inheritance Mechanism of dojo:(See the bold font description)

..................

If (OPTs. Call (superclass)
= "[Object array]") {
// Sort the array of base classes when multiple base classes exist.

Bases =
C3mro (superclass );
T = bases [0];
Mixins = bases. Length-T;


// The first object in the base class Array

Superclass = bases [mixins];
} Else {


// Only one base class

Bases = [0];
If (superclass ){

If (OPTs. Call (superclass) = "[object function]") {
T =
Superclass. _ Meta;
Bases = bases. Concat (T? T. bases:
Superclass );
} Else {
Err ("base class is not a callable
Constructor .");
}
} Else if (superclass! = NULL ){

Err ("unknown base class. Did you use dojo. Require To pull it in? ")

}
}

// Start to construct base class attributes and merge their prototype content

If (superclass ){
For (I = mixins-1; -- I ){


// Copy prototype

,Superclass is the first function object in the base class array. After forcenew, it becomes a prototype containing superclass.
An object of an attribute


PROTO = forcenew (superclass );

If (! I ){
// Stop if nothing to add (the last Base)

Break;
}
// Mix in properties
T = bases [I];


// Merge the prototypes of all base classes and use them as the prototypes of the subsequent sub-classes to share attributes.

(T. _ Meta
? Mixown: mix) (PROTO, T. Prototype );
// Construct
Merge prototype-based temporary function objects of the base class


Ctor = new function;

Ctor. superclass = superclass;
Ctor. Prototype = proto;



Superclass = Proto. constructor = ctor;


// The above line of code is used to adjust the constructor of the constructor constructed, maintain consistency, and then modify the superclass for subsequent iteration. In fact, this line is written into the following two lines for better understanding:


// Ctor. Prototype. constructor = ctor;

// Superclass = ctor;


}
} Else {
PROTO = {};
}

.................

 

 

 

Here we just roughly repeat the main line of dojo. Declare, followed by the source code of dojo. Declare (based on dojo1.5). You can refer to it. For more information about dojo. the implementation details of declare are much more worth discussing. However, due to the long length, we will continue to discuss the detailed implementation of Dojo's object-oriented mechanism.

 

Dojo. Declare and dojo. Require (similar to Java import) and dojo. Provide
These three functions are used together to encapsulate Javascript into a dojo language mode that is close to object-oriented, which is a unique feature of dojo compared to other web control libraries.

 

Another point: in Dojo. the declare method also implements a useful chain mechanism, which is used by defining the "-chains-" variable. If you are interested, you can study it. I will not describe it too much here.

 

 

 

 

 

 

 

 

Add the dojo. Declare source code: (dojo1.5)

 

D. Declare =
Function (classname, superclass, props ){
// Crack Parameters

If (typeof classname! = "String "){
Props = superclass;

Superclass = classname;
Classname = "";

}
Props = props | | {};


VaR proto, I, T, ctor, name, bases,
Chains, mixins = 1, parents = superclass;


// Build
Prototype
If (OPTs. Call (superclass) = "[object array]") {

// C3 Mro
Bases = c3mro (superclass );
T =
Bases [0];
Mixins = bases. Length-T;
Superclass =
Bases [mixins];
} Else {
Bases = [0];

If (superclass ){
If (OPTs. Call (superclass) = "[Object
Function] ") {
T = superclass. _ Meta;

Bases = bases. Concat (T? T. Bases: superclass );
} Else {

Err ("base class is not a callable constructor .");

}
} Else if (superclass! = NULL ){

Err ("unknown base class. Did you use dojo. Require To pull it in? ")

}
}
If (superclass ){
For (I = mixins-
1; -- I ){
PROTO = forcenew (superclass );

If (! I ){
// Stop if nothing to add (the last Base)

Break;
}
// Mix in
Properties
T = bases [I];
(T. _ meta? Mixown
: Mix) (PROTO, T. Prototype );
// Chain in new
Constructor
Ctor = new function;

Ctor. superclass = superclass;
Ctor. Prototype = proto;

Superclass = Proto. constructor = ctor;
}

} Else {
PROTO = {};
}
// Add all
Properties
Safemixin (PROTO, props );
// Add
Constructor
T = props. constructor;
If (T! =
Op. constructor ){
T. Nom = cname;
Proto. Constructor
= T;
}


// Collect chains and flags

For (I = mixins-1; I; -- I) {// intentional assignment
T =
Bases [I]. _ Meta;
If (T & T. Chains ){

Chains = mix (chains | |{}, T. Chains );
}
}

If (PROTO ["-chains-"]) {
Chains = mix (chains || {},
PROTO ["-chains-"]);
}


// Build ctor
T =! Chains |
! Chains. hasownproperty (cname );
Bases [0] = ctor = (chains &&
Chains. constructor = "Manual ")? Simpleconstructor (bases ):

(Bases. Length = 1? Singleconstructor (props. constructor, T ):
Chainedconstructor (bases, t ));


// Add meta information to
Constructor
Ctor. _ meta = {bases: bases, hidden: props, Chains:
Chains,
Parents: parents, ctor: props. constructor };

Ctor. superclass = superclass & superclass. Prototype;

Ctor. Extend = extend;
Ctor. Prototype = proto;

Proto. constructor = ctor;


// Add "standard" methods to
Prototype
Proto. getinherited = getinherited;

Proto. inherited = inherited;
Proto. isinstanceof =
Isinstanceof;


// Add name if specified

If (classname ){
Proto. declaredclass = classname;

D. setobject (classname, ctor );
}


// Build
Chains and add them to the prototype
If (chains ){

For (name in chains ){
If (PROTO [name] & typeof
Chains [name] = "string" & name! = Cname ){
T =
PROTO [name] = chain (name, bases, chains [name] = "after ");

T. Nom = Name;
}
}
}

// Chained methods do not return values
// No need to chain
"Invisible" Functions


Return ctor; // Function

};

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.