From:/?id=2
One, background
Looking back at the development of programming languages, it is not difficult to find that this is a process of continuous encapsulation: from the initial assembly language, to procedural language, then to object-oriented language, and then to scripting languages with object-oriented characteristics, encapsulation layer by layer, step by step, reducing the burden on programmers and gradually improving the efficiency of writing programs. This article is about JavaScript, so let’s first understand what language JavaScript is. So far, JavaScript is a scripting language that does not fully support object-oriented features. The reason for saying this is because JavaScript does support the concept of objects. In programs, we see that they are all objects, but Javascipt does not support class encapsulation and inheritance. Readers who have had C++, Java, or php, or python programming experience will know that these languages allow us to use classes to design objects, and that these classes are inheritable. JavaScript does support custom objects and inheritance, but it uses another method: prototype (Chinese translation: prototype). Readers who have used JavaScript or read "Design Patterns" will understand this technology, as described below:
Each object contains a prototype object. When querying an attribute or requesting a method from the object, the running environment will first look up in the current object. If the search fails, look up its prototype object. Note that prototype is also an object, so this search process also applies to the object's prototype object until the current object's prototpye is empty.
In JavaScript, the prototype of the object is not visible during the runtime and can only be set before creating the object when defining the constructor of the object. The following usages are all wrong:
= o1;
/*
At this time, only one attribute named "prototype" of o2 is defined.
There is no prototype with o1 as o2.
*/
// ---------------
f2 = function(){};
o2 = new f2;
= o1;
/*
At this time, o1 did not become the prototype of o2.
Because o2 has been created before f2 sets prototype.
*/
// ---------------
f1 = function(){};
f2 = function(){};
o1 = new f1;
= o1;
o2 = new f2;
/*
Similarly, at this time, o1 is not the prototype of o2.
Because JavaScript does not allow constructor prototype objects to be directly referenced by other variables.
*/
The correct usage should be:
f1 = function(){};
f2 = function(){};
= new f1;
o2 = new f2;
As can be seen from the above example: If you want constructor F2 to inherit the properties and methods defined by another constructor F1, then you must first create an instance object of F1 and immediately set it to F2’s prototype. So you will find that using prototype is actually discouraged from using inheritance: on the one hand, because JavaScript is designed as an embedded scripting language. For example, embedded in the browser, the applications written with it are generally not very large or complex, and there is no need to use inheritance; on the other hand, if the inheritance is deep, the prototype chain will be longer, and the time spent on finding object properties and methods will become longer, reducing the overall operation efficiency of the program.
Two, the problem
Now there are more and more JavaScript used, and a very important aspect of web2.0 is user experience. A good user experience not only requires artists to do well, but also emphasizes response speed and dynamic effects. Many famous web2.0 applications use a large amount of JavaScript code, such as Flickr, Gmail, etc. Some people even use Javasript to write browser-based GUIs, such as Backbase, Qooxdoo, etc. Therefore, the development and maintenance of JavaScript code has become a very important issue. Many people don’t like to invent their own wheels. They hope that JavaScript can have a mature and stable Javasript library like other programming languages to improve their development speed and efficiency. What more people hope is that the JavaScript code they write can have good modular features and good reusability like code written in other object-oriented languages, which will be more convenient to maintain. However, JavaScript does not support these needs very well. Most development needs to be started over and it is very inconvenient to maintain.
3. There are already solutions
There will naturally be solutions when there is a need. There are two more mature ones:
1. Nowadays, many people use a set of JavaScript libraries called “ in their projects. It is developed by the MVC web framework Ruby on Rails and uses the JavaScript basic library. This library is well designed and has good reusability and cross-browser features. It can greatly simplify the development of client code. The concept of a class is introduced. The class written in it can define an initialize initialization function. This initialization function will be called first when creating a class instance. As its name suggests, the core of the prototype is still the prototype. Although it provides a lot of reusable code, it does not fundamentally solve the development and maintenance problems of JavaScript.
2. People who use it usually hear or use a framework called Atlas, which is Microsoft's AJAX weapon. Atlas allows client code to be written using class methods, and has better object-oriented features than , such as defining private properties and private methods of a class, supporting inheritance, writing interfaces like Java, etc. Atlas is a solution from the client to the server, but it can only be used in the context, copyright and other issues limit its scope of use.
There is only one fundamental solution to the problem, which is to wait for the release of the JavaScript 2.0 (or ECMAScript 4.0) standard. The next version of JavaScript already has the language-oriented feature. In addition, Microsoft's can already use these features. Of course, waiting is not a wise approach.
Fourth, Modello framework
If the above statement makes you feel a little dizzy, it is best not to rush to understand the Modello framework. First, make sure that you can accurately understand these concepts:
JavaScript constructor: In JavaScript, custom objects are designed through constructors. Operator new plus constructor will create an instance object
Prototype in JavaScript: If an object P is set as a prototype of a constructor F, then the instance object created using F will inherit the properties and methods of P.
Class: Object-oriented language uses classes to encapsulate and design objects. Class members are divided into attributes and methods by type. Class members are divided into static members, private members, protected members, and public members by access rights.
Class inheritance: Object-oriented language allows one class to inherit the properties and methods of another class. The inherited class is called a subclass and the inherited class is called a parent class. Some languages allow a subclass to inherit only one parent class (single inheritance), while some languages allow multiple inheritance (multiple inheritance)
closure feature in JavaScript: The scope of a function is a closure. JavaScript allows internal function I to be defined in function O, which 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. In other words, if you define a variable V in the constructor C and a function F with this, when the instance object O created by C is called, F can always access V, but it is not possible to access it in this way, because V is not defined with this. In other words, V becomes a private member of O. This feature is very important. If you haven't fully understood it, please refer to this article "Private Members in JavaScript"
It is no longer difficult for you to understand the above concept and understand the following content. Let’s get started!
As the title says, Modello is a framework that allows and encourages you to write classes in JavaScript. Traditional JavaScript uses constructors to customize objects and uses prototype to implement inheritance. In Modello, you can forget the obscure prototype, because Modello uses classes to design objects and uses classes to implement inheritance, just like other object-oriented languages, and is easier to use. Don't believe it? Please continue reading.
Classes written using Modello have the following features:
Private members, public members and static members
Inheritance of classes, multiple inheritance
Namespace
Type identification
Modello also has the following features:
Less concepts, more convenient way to use
Small, only about two hundred lines of code
The design period and the running period are completely separated. There is no need to use prototype when using inheritance, nor do you need to create an instance of the parent class first.
Compatible with class, compatible with JavaScript constructor
Cross-browser, cross-browser version
Open source, BSD licensed, allowed for free use in personal or commercial projects
The following is a description of how to use Modello:
1. Define a class
Point = ();
/*
Create a class. People who have used it think it is very familiar to you;)
*/
2. Register a class
("");
/*
Here "Modello" is the namespace, and "Point" is the class name, separated by "."
If the registration is successful,
Equal to "Modello", equal to "Point".
If it fails, Modello will throw an exception, indicating the reason for the failure.
*/
("Point"); // The default namespace "std" is used here
(Point, "Point"); // Use Class register method
3. Get registered class
P = ("");
P = ("Point"); // The default namespace "std" is used here
4. Use inheritance
ZPoint = (Point); // ZPoint Inheritance Point
ZPoint = (""); // Inherit the registered class
ZPoint = (Point1, Point2[, ...]);
/*
Inherit more. The class in the parameter can also be replaced by the registered class name.
*/
/*
Inheritance relationship:
The content is [ ZPoint ]
The content is [ Point ]
*/
5. Define the static member of the class
= 0;
= function(x, y) {
return x + y;
}
6. Define the constructor of the class
= function($self, $class) {
// Use "var" to define private members
var _name = "";
var _getName = function () {
return _name;
}
// Use "this" to define public members
= 0;
= 0;
= function (x, y) { // Initialization function
= x;
= y;
$ += 1; // Accessing static members
// Public methods access private property
= function (name) {
_name = name;
}
= function () {
return _getName();
}
= function () {
return "Point(" + + ", " + + ")";
}
// Note: The initialize and toString methods will only take effect if they are defined as public members.
= function() {
// Call the static method and use the $class passed in by the constructor
return $(, );
}
}
= function($self, $class) {
= 0;//, Inherited from Point
// Overload Point’s initialization function
= function (x, y, z) {
= z;
// Call the initialization function of the first parent class,
// The second parent class is $self.super1, and so on.
Note: The $self variable passed in by the constructor is used here
$self.(this, x, y);
// This method can be used for any method calling the parent class, but only for the public methods of the parent class
}
// The toString method of overloading Point
= function () {
return "Point(" + + ", " + +
", " + + ")";
}
}
// Continuous writing skills
().register("").construct = function($self, $class) {
// ...
}
7. Create an instance of the class
// Two methods: new and create
point = new Point(1, 2);
point = (1, 2);
point = ("").create(1, 2);
zpoint = new ZPoint(1, 2, 3);
8. Type identification
(Point); // Return true
(Point); // Return true
(Point); // Return true
(Point); // Return true
(Point); // Return false
//The above classes can be replaced with registered class names
The above are all the functions provided by Modello. Here are some precautions and suggestions for using Modello:
When using inheritance, the passed parent class can be a class defined in the form of or a constructor defined in the form of JavaScript
The class is actually a function, and the inheritance method of ordinary prototypes is also applicable to classes defined with Modelo
Classes can not be registered. This kind of class is called anonymous class and cannot be obtained through the method.
If you define a class constructor, two parameters $self and $class are provided as in the above example, Modelo will pass the instance itself to $self when creating the instance and pass the class itself to $class. $self is usually used when accessing parent class members, and $class is usually used when accessing static members. Although $self and $class are very powerful, it is not recommended that you use it in other occasions unless you have already understood the source code of Modello and do have special needs. Don't try to use $self instead of this, as this may cause you trouble
The subclass cannot access the private members of the parent class, and the private members cannot be accessed in the static method.
There is no special restriction on the name of private members in Modello, but it is a good habit to start with "_"
Modello does not support protected members. If you want the parent class member to be accessed by a child class, you must define the parent class member as public. You can also refer to the naming method of "this._property" to represent protection members:)
Try to define some auxiliary calculation complex methods as static members, so as to improve operational efficiency.
You can use Modello’s inheritance and type authentication to implement basic interface functions, you have already discovered this;)
When using multiple inheritance, the parent class on the left has higher priority than the parent class on the right. That is to say, if multiple parent classes define the same method, the method defined by the leftmost parent class will eventually be inherited.
The class functions written with Modello are comparable to those written with Atlas, and are more concise to use. If you want to use the Modello framework instead of the simple class framework in the class, you just need to include it first and then remove the few lines of code that defines Class in the class, and everything will run normally.
If you find a bug in Modello, you are very welcome to contact me via email. If you think Modello should have more functions, you can try reading the source code and you will find that Modello can easily extend the functions you need.
Modello is originally meant as "a model of large-scale art works". I hope Modello can help you write high-quality JavaScript code.
5. Download
Modello’s complete reference instructions and download address:
One, background
Looking back at the development of programming languages, it is not difficult to find that this is a process of continuous encapsulation: from the initial assembly language, to procedural language, then to object-oriented language, and then to scripting languages with object-oriented characteristics, encapsulation layer by layer, step by step, reducing the burden on programmers and gradually improving the efficiency of writing programs. This article is about JavaScript, so let’s first understand what language JavaScript is. So far, JavaScript is a scripting language that does not fully support object-oriented features. The reason for saying this is because JavaScript does support the concept of objects. In programs, we see that they are all objects, but Javascipt does not support class encapsulation and inheritance. Readers who have had C++, Java, or php, or python programming experience will know that these languages allow us to use classes to design objects, and that these classes are inheritable. JavaScript does support custom objects and inheritance, but it uses another method: prototype (Chinese translation: prototype). Readers who have used JavaScript or read "Design Patterns" will understand this technology, as described below:
Each object contains a prototype object. When querying an attribute or requesting a method from the object, the running environment will first look up in the current object. If the search fails, look up its prototype object. Note that prototype is also an object, so this search process also applies to the object's prototype object until the current object's prototpye is empty.
In JavaScript, the prototype of the object is not visible during the runtime and can only be set before creating the object when defining the constructor of the object. The following usages are all wrong:
= o1;
/*
At this time, only one attribute named "prototype" of o2 is defined.
There is no prototype with o1 as o2.
*/
// ---------------
f2 = function(){};
o2 = new f2;
= o1;
/*
At this time, o1 did not become the prototype of o2.
Because o2 has been created before f2 sets prototype.
*/
// ---------------
f1 = function(){};
f2 = function(){};
o1 = new f1;
= o1;
o2 = new f2;
/*
Similarly, at this time, o1 is not the prototype of o2.
Because JavaScript does not allow constructor prototype objects to be directly referenced by other variables.
*/
The correct usage should be:
f1 = function(){};
f2 = function(){};
= new f1;
o2 = new f2;
As can be seen from the above example: If you want constructor F2 to inherit the properties and methods defined by another constructor F1, then you must first create an instance object of F1 and immediately set it to F2’s prototype. So you will find that using prototype is actually discouraged from using inheritance: on the one hand, because JavaScript is designed as an embedded scripting language. For example, embedded in the browser, the applications written with it are generally not very large or complex, and there is no need to use inheritance; on the other hand, if the inheritance is deep, the prototype chain will be longer, and the time spent on finding object properties and methods will become longer, reducing the overall operation efficiency of the program.
Two, the problem
Now there are more and more JavaScript used, and a very important aspect of web2.0 is user experience. A good user experience not only requires artists to do well, but also emphasizes response speed and dynamic effects. Many famous web2.0 applications use a large amount of JavaScript code, such as Flickr, Gmail, etc. Some people even use Javasript to write browser-based GUIs, such as Backbase, Qooxdoo, etc. Therefore, the development and maintenance of JavaScript code has become a very important issue. Many people don’t like to invent their own wheels. They hope that JavaScript can have a mature and stable Javasript library like other programming languages to improve their development speed and efficiency. What more people hope is that the JavaScript code they write can have good modular features and good reusability like code written in other object-oriented languages, which will be more convenient to maintain. However, JavaScript does not support these needs very well. Most development needs to be started over and it is very inconvenient to maintain.
3. There are already solutions
There will naturally be solutions when there is a need. There are two more mature ones:
1. Nowadays, many people use a set of JavaScript libraries called “ in their projects. It is developed by the MVC web framework Ruby on Rails and uses the JavaScript basic library. This library is well designed and has good reusability and cross-browser features. It can greatly simplify the development of client code. The concept of a class is introduced. The class written in it can define an initialize initialization function. This initialization function will be called first when creating a class instance. As its name suggests, the core of the prototype is still the prototype. Although it provides a lot of reusable code, it does not fundamentally solve the development and maintenance problems of JavaScript.
2. People who use it usually hear or use a framework called Atlas, which is Microsoft's AJAX weapon. Atlas allows client code to be written using class methods, and has better object-oriented features than , such as defining private properties and private methods of a class, supporting inheritance, writing interfaces like Java, etc. Atlas is a solution from the client to the server, but it can only be used in the context, copyright and other issues limit its scope of use.
There is only one fundamental solution to the problem, which is to wait for the release of the JavaScript 2.0 (or ECMAScript 4.0) standard. The next version of JavaScript already has the language-oriented feature. In addition, Microsoft's can already use these features. Of course, waiting is not a wise approach.
Fourth, Modello framework
If the above statement makes you feel a little dizzy, it is best not to rush to understand the Modello framework. First, make sure that you can accurately understand these concepts:
JavaScript constructor: In JavaScript, custom objects are designed through constructors. Operator new plus constructor will create an instance object
Prototype in JavaScript: If an object P is set as a prototype of a constructor F, then the instance object created using F will inherit the properties and methods of P.
Class: Object-oriented language uses classes to encapsulate and design objects. Class members are divided into attributes and methods by type. Class members are divided into static members, private members, protected members, and public members by access rights.
Class inheritance: Object-oriented language allows one class to inherit the properties and methods of another class. The inherited class is called a subclass and the inherited class is called a parent class. Some languages allow a subclass to inherit only one parent class (single inheritance), while some languages allow multiple inheritance (multiple inheritance)
closure feature in JavaScript: The scope of a function is a closure. JavaScript allows internal function I to be defined in function O, which 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. In other words, if you define a variable V in the constructor C and a function F with this, when the instance object O created by C is called, F can always access V, but it is not possible to access it in this way, because V is not defined with this. In other words, V becomes a private member of O. This feature is very important. If you haven't fully understood it, please refer to this article "Private Members in JavaScript"
It is no longer difficult for you to understand the above concept and understand the following content. Let’s get started!
As the title says, Modello is a framework that allows and encourages you to write classes in JavaScript. Traditional JavaScript uses constructors to customize objects and uses prototype to implement inheritance. In Modello, you can forget the obscure prototype, because Modello uses classes to design objects and uses classes to implement inheritance, just like other object-oriented languages, and is easier to use. Don't believe it? Please continue reading.
Classes written using Modello have the following features:
Private members, public members and static members
Inheritance of classes, multiple inheritance
Namespace
Type identification
Modello also has the following features:
Less concepts, more convenient way to use
Small, only about two hundred lines of code
The design period and the running period are completely separated. There is no need to use prototype when using inheritance, nor do you need to create an instance of the parent class first.
Compatible with class, compatible with JavaScript constructor
Cross-browser, cross-browser version
Open source, BSD licensed, allowed for free use in personal or commercial projects
The following is a description of how to use Modello:
1. Define a class
Point = ();
/*
Create a class. People who have used it think it is very familiar to you;)
*/
2. Register a class
("");
/*
Here "Modello" is the namespace, and "Point" is the class name, separated by "."
If the registration is successful,
Equal to "Modello", equal to "Point".
If it fails, Modello will throw an exception, indicating the reason for the failure.
*/
("Point"); // The default namespace "std" is used here
(Point, "Point"); // Use Class register method
3. Get registered class
P = ("");
P = ("Point"); // The default namespace "std" is used here
4. Use inheritance
ZPoint = (Point); // ZPoint Inheritance Point
ZPoint = (""); // Inherit the registered class
ZPoint = (Point1, Point2[, ...]);
/*
Inherit more. The class in the parameter can also be replaced by the registered class name.
*/
/*
Inheritance relationship:
The content is [ ZPoint ]
The content is [ Point ]
*/
5. Define the static member of the class
= 0;
= function(x, y) {
return x + y;
}
6. Define the constructor of the class
= function($self, $class) {
// Use "var" to define private members
var _name = "";
var _getName = function () {
return _name;
}
// Use "this" to define public members
= 0;
= 0;
= function (x, y) { // Initialization function
= x;
= y;
$ += 1; // Accessing static members
// Public methods access private property
= function (name) {
_name = name;
}
= function () {
return _getName();
}
= function () {
return "Point(" + + ", " + + ")";
}
// Note: The initialize and toString methods will only take effect if they are defined as public members.
= function() {
// Call the static method and use the $class passed in by the constructor
return $(, );
}
}
= function($self, $class) {
= 0;//, Inherited from Point
// Overload Point’s initialization function
= function (x, y, z) {
= z;
// Call the initialization function of the first parent class,
// The second parent class is $self.super1, and so on.
Note: The $self variable passed in by the constructor is used here
$self.(this, x, y);
// This method can be used for any method calling the parent class, but only for the public methods of the parent class
}
// The toString method of overloading Point
= function () {
return "Point(" + + ", " + +
", " + + ")";
}
}
// Continuous writing skills
().register("").construct = function($self, $class) {
// ...
}
7. Create an instance of the class
// Two methods: new and create
point = new Point(1, 2);
point = (1, 2);
point = ("").create(1, 2);
zpoint = new ZPoint(1, 2, 3);
8. Type identification
(Point); // Return true
(Point); // Return true
(Point); // Return true
(Point); // Return true
(Point); // Return false
//The above classes can be replaced with registered class names
The above are all the functions provided by Modello. Here are some precautions and suggestions for using Modello:
When using inheritance, the passed parent class can be a class defined in the form of or a constructor defined in the form of JavaScript
The class is actually a function, and the inheritance method of ordinary prototypes is also applicable to classes defined with Modelo
Classes can not be registered. This kind of class is called anonymous class and cannot be obtained through the method.
If you define a class constructor, two parameters $self and $class are provided as in the above example, Modelo will pass the instance itself to $self when creating the instance and pass the class itself to $class. $self is usually used when accessing parent class members, and $class is usually used when accessing static members. Although $self and $class are very powerful, it is not recommended that you use it in other occasions unless you have already understood the source code of Modello and do have special needs. Don't try to use $self instead of this, as this may cause you trouble
The subclass cannot access the private members of the parent class, and the private members cannot be accessed in the static method.
There is no special restriction on the name of private members in Modello, but it is a good habit to start with "_"
Modello does not support protected members. If you want the parent class member to be accessed by a child class, you must define the parent class member as public. You can also refer to the naming method of "this._property" to represent protection members:)
Try to define some auxiliary calculation complex methods as static members, so as to improve operational efficiency.
You can use Modello’s inheritance and type authentication to implement basic interface functions, you have already discovered this;)
When using multiple inheritance, the parent class on the left has higher priority than the parent class on the right. That is to say, if multiple parent classes define the same method, the method defined by the leftmost parent class will eventually be inherited.
The class functions written with Modello are comparable to those written with Atlas, and are more concise to use. If you want to use the Modello framework instead of the simple class framework in the class, you just need to include it first and then remove the few lines of code that defines Class in the class, and everything will run normally.
If you find a bug in Modello, you are very welcome to contact me via email. If you think Modello should have more functions, you can try reading the source code and you will find that Modello can easily extend the functions you need.
Modello is originally meant as "a model of large-scale art works". I hope Modello can help you write high-quality JavaScript code.
5. Download
Modello’s complete reference instructions and download address: