from:http://www.ajaxwing.com/index.php?id=2
One, background
Looking back at the development of programming languages, it's not hard to see that this is a process that is constantly encapsulated: from the beginning of assembly language, to the process-oriented language, and then to object-oriented language, and then to a scripting language with object-oriented features, a layer of encapsulation, step-by-step to reduce the burden on programmers, and gradually improve the efficiency of writing programs. This article is about JavaScript, so let's take a look at how JavaScript is a language. So far, JavaScript is a scripting language that does not fully support object-oriented features. This is because JavaScript does support the concept of objects, we see objects in the program, but Javascipt does not support the encapsulation and inheritance of classes. Readers who have had C + +, Java, or PHP and Python programming experience will know that these languages allow us to design objects using classes, and that these classes are inheritable. JavaScript does support custom objects and inheritance, but in another way: prototype (Chinese translation: prototype). Readers who have used JavaScript or read design patterns will understand this technique, described below:
Each object contains a prototype object, and when you query an object for a property or request a method, the runtime looks in the current object first and finds its prototype object if the lookup fails. Note that prototype is also an object, so this lookup procedure also applies to the object's prototype object until the current object's Prototpye is empty.
In JavaScript, the prototype of an object is not visible at runtime and can only be set before an object is created when the object's constructor is defined. The following usage is all wrong:
O2.prototype = O1;
/*
A property named "prototype" for O2 is defined at this time.
The O1 is not set to O2 prototype.
*/
// ---------------
F2 = function () {};
O2 = new F2;
F2.prototype = O1;
/*
At this time O1 did not become O2 's prototype,
Because O2 was created before F2 set prototype.
*/
// ---------------
F1 = function () {};
F2 = function () {};
O1 = new F1;
F2.prototype = O1;
O2 = new F2;
/*
Again, O1 is not the prototype of O2,
Because JavaScript does not allow the prototype object of a constructor to be referenced directly by other variables.
*/
The correct usage should be:
F1 = function () {};
F2 = function () {};
F2.prototype = new F1;
O2 = new F2;
As you can see from the example above: if you want the constructor F2 to inherit another constructor F1 the defined properties and methods, you must first create a F1 instance object and immediately set it to F2 prototype. So you'll find that using prototype this inheritance method actually discourages the use of inheritance: On the one hand, JavaScript is designed as an embedded scripting language, for example, embedded in the browser, the application written with it is generally not very complex, do not need to use the inheritance On the other hand, if the inheritance is deeper, the prototype chain will be longer, the time used to find object properties and methods will be longer, reducing the overall operating efficiency of the program.
Second, the question
Now that the use of JavaScript more and more, web2.0 has a very important aspect is the user experience. A good user experience not only requires the artist to do well, but also emphasizes the response speed and dynamic effect. Many famous web2.0 apps use a lot of JavaScript code, such as Flickr, Gmail, and so on. Even some people use Javasript to write browser-based GUIs, such as Backbase, Qooxdoo, and so on. So the development and maintenance of JavaScript code has become a very important issue. Many people do not like to invent their own wheels, they want JavaScript to be like other programming languages, a mature and stable javasript library to improve their development speed and efficiency. What more people want is that their JavaScript code, like other object-oriented language code, has a good modularity and reusability, which makes it easier to maintain. But now JavaScript does not support these needs very well, most of the development will start from the beginning, and maintenance is very inconvenient.
Third, there are already solutions
There is a need to naturally have a solution, more mature there are two kinds:
1, a lot of people now use a JavaScript library called Prototype.js in their own projects, developed by the MVC Web framework Ruby on Rails and use the JavaScript base library. This library is well-designed and has good reusability and cross-browser features, and using prototype.js can greatly simplify the development of client code. Prototype.js introduces the concept of a class that can be written with a class that defines a initialize initialization function, which is invoked first when the class instance is created. As its name, Prototype.js's core or prototype, while providing a lot of reusable code, does not fundamentally address the development and maintenance of JavaScript.
2, people who use asp.net often hear or use a framework called Atlas, which is a Microsoft AJAX tool. Atlas allows client code to be written in class, and has better object-oriented attributes than prototype.js, such as defining private and private methods for classes, supporting inheritance, writing interfaces like Java, and so on. Atlas is a solution from client to server, but it can only be used in asp.net, copyright, and so on, limiting its scope of use.
The only solution to the problem is to wait for the JavaScript2.0 (or ECMAScript4.0) standard to be introduced. Language-oriented features are already available in the next version of JavaScript. In addition, Microsoft's JScript.NET has already been able to use these features. Of course, waiting is not a sensible way.
Iv. the Modello framework
If the above statement makes you feel a little dizzy, it is best not to rush to understand the Modello framework, first of all to ensure that these concepts you have been able to accurately understand:
JavaScript constructors: In JavaScript, custom objects are designed by constructors. operator new plus the constructor creates an instance object
Prototype in JavaScript: If an object P is set to the prototype of a constructor F, the instance object created using F inherits the properties and methods of P
Class: Object-oriented language uses classes to encapsulate and design objects. Members of a class are grouped into properties and methods by type. The members of a class are divided into static members, private members, protected members, and public members by access rights.
Class inheritance: Object-oriented languages allow one class to inherit the properties and methods of another class, and the inherited class is called a subclass, and the inherited class is called the parent class. Some languages allow a subclass to inherit only one parent class (single inheritance), and some languages allow multiple inheritance (multiple inheritance)
Closure features in JavaScript: The scope of a function is a closure. JavaScript allows you to define internal functions I in function o, and internal functions I can always access variables defined in its external function O. Even after the external function o returns, you call the internal function I, and you can also access the variables defined in the external function O. That is, if you define a variable V with Var in constructor C, and use this to define a function f, when the instance object O of C is called O.F, F always has access to V, but access with O.V is not possible, because V is not defined with this. In other words, V becomes a private member of O. This feature is very important, if you have not thoroughly understood, please refer to this article "Private members in JavaScript"
Understand the above concept, understanding the following content for you have no difficulty, to begin!
As the title, Modello is a framework that allows and encourages you to write classes using JavaScript. Traditional JavaScript uses constructors to customize objects, using prototype to implement inheritance. In Modello, you can forget obscure prototype, because Modello uses classes to design objects, and implements inheritance with classes, just like other object-oriented languages, and is simpler to use. You don't believe me? Please continue to look down.
Classes written using Modello have the following characteristics:
Private members, public members, and static members
Inheritance of classes, multiple inheritance
Name space
Type identification
Modello also has the following characteristics:
Fewer concepts, more convenient ways to use
Small, only about 200 lines of code
The design period and run time are completely separated, the use of inheritance does not require the use of prototype, and do not need to create an instance of the parent class first
Compatible prototype.js classes, JavaScript-compatible constructors
Cross-browser, cross-browser version
Open source, BSD licenced, free to use in personal projects or business projects
The following is a description of how modello is used:
1, define a class
Point = Class.create ();
/*
Create a class. People who have used prototype.js feel very familiar with it;
*/
2, register a class
Point.register ("Modello.point");
/*
Here "modello" is the namespace, "point" is the class name, between "." Separated
If the registration is successful,
Point.namespace equals "modello", Point.classname equals "point".
If the failure modello throws an exception that explains the reason for the failure.
*/
Point.register ("point"); This uses the default namespace, "Std"
Class.register (Point, "point"); Register method with Class
3, get the registered class
P = Class.get ("Modello.point");
P = Class.get ("point"); This uses the default namespace, "Std"
4, using inheritance
Zpoint = Class.create (point); Zpoint Inherits Point
Zpoint = Class.create ("Modello.point"); Inheriting a registered class
Zpoint = Class.create (Point1, point2[, ...));
/*
Multiple inheritance. The class in the parameter can also be replaced with the registered class name
*/
/*
Inheritance Relationship:
Point.subclasses content is [Zpoint]
Zpoint.superclasses content is [point]
*/
5, define the static members of the class
Point.count = 0;
Point.add = function (x, y) {
return x + y;
}
6, defining constructors for classes
Point.construct = function ($self, $class) {
Define private members with "Var"
var _name = "";
var _getname = function () {
return _name;
}
Use "This" to define public members
this.x = 0;
This.y = 0;
This.initialize = function (x, y) {//initialization functions
this.x = x;
This.y = y;
$class. Count + 1; accessing static members
Public method Access private private property
This.setname = function (name) {
_name = name;
}
This.getname = function () {
return _getname ();
}
this.tostring = function () {
Return "point" ("+ this.x +", "+ This.y +") ";
}
Note: The Initialize and ToString methods take effect only if they are defined as public members
This.add = function () {
Call the static method, using the constructor to pass in the $class
Return $class. Add (this.x, THIS.Y);
}
}
Zpoint.construct = function ($self, $class) {
this.z = 0; This.x, This.y inherits from Point
Overload Point initialization function
This.initialize = function (x, y, z) {
This.z = Z;
Invokes the initialization function of the first parent class,
The second parent class is $self. Super1, and so on.
Note: Here is the $self variable that the constructor passed in
$self. Super0.initialize.call (this, x, y);
Any method that invokes the parent class can be used in this way, but only to the public method of the parent class
}
The ToString method for overloaded point
this.tostring = function () {
Return "point" ("+ this.x +", "+ This.y +
"," + This.z + ")";
}
}
ligatures Tips
Class.create (). Register ("Modello.point"). Construct = function ($self, $class) {
// ...
}
7, create an instance of the class
Two ways: New and create
Point = new Point (1, 2);
Point = Point.create (1, 2);
Point = Class.get ("Modello.point"). Create (1, 2);
Zpoint = new Zpoint (1, 2, 3);
8, type identification
Zpoint.subclassof (point); Returns True
Point.instanceof (point); Returns True
Point.isa (point); Returns True
Zpoint.isa (point); Returns True
Zpoint.instanceof (point); return False
The class above can be replaced with the registered class name
These are all the features provided by Modello. Here are some caveats and suggestions for using Modello:
When using inheritance, the incoming parent class can be a constructor defined using a class or JavaScript method defined by the Prototype.js method
A class is actually also a function, and normal prototype inheritance is equally applicable to classes defined with Modello
Class can not be registered, this class is called anonymous class and cannot be obtained through the Class.get method
If you define a class constructor, which provides $self as in the example above, $class two parameters, Modello passes the instance itself to the $self when the instance is created, passing the class itself to $class. $self are typically used when accessing a parent class member, $class are generally used when accessing static members. Although $self and $class functions are powerful, it is not recommended that you use them on other occasions unless you have read the source code of Modello and do have special needs. Do not try to use $self instead of this, which may cause trouble to you
Subclasses cannot access private members of the parent class, and private members cannot be accessed in static methods
There are no special restrictions on the names of private members in Modello, but starting with "_" is a good habit
Modello does not support protection (protected) members, if you want the parent class member to be able to access the quilt class, you must define the parent class member as public. You can also refer to the name "This._property" to indicate the protection of members:
As far as possible, some auxiliary computational complexity method is defined as static member, which can improve the efficiency of operation.
Using Modello inheritance and type identification enables basic interface (interface) functionality, which you have found.
When you use multiple inheritance, the parent class on the left has precedence over the parent on the right. That is, if multiple parent classes define the same method, the leftmost parent class defines a method that is eventually inherited
The class features written using Modello can be comparable to those written using Atlas and are simpler to use. If you want to use the Modello framework instead of the simple class framework in prototype.js, you just need to include modello.js, and then remove the lines of code that define class in Prototype.js, and everything will work.
If you find Modello bugs, you are very welcome to contact me by email. If you think modello should have more features, you can try to read the source code and you'll find that Modello can easily expand the functionality you need.
Modello is meant to be "a model of large art works" and hopefully Modello can help you write high-quality JavaScript code.
5, download
Full reference and download address of modello: http://modello.sourceforge.net