Create classes and objects in JS

Source: Internet
Author: User


Several methods for creating classes/objects in Javascript

In JS, the create object is not exactly the class object that we often call to create. The objects in JS emphasize a composite type, creating objects in JS and accessing objects are extremely flexible.

Javascript objects are a composite type that allows you to store and access them through variable names. In another way, an object is a disordered set of attributes, each item in the set is composed of names and values (does it sound like hash tables, dictionaries, and healthy/value pairs we often hear about ?), The value type may be a built-in type (such as number or string) or an object.

I. enclosed by a pair of braces
VaR emptyobj = {};
VaR myobj =
{
'Id': 1, // attribute names are enclosed by quotation marks, and attributes are separated by commas.
'Name': 'myname'
};
// Var M = new myobj (); // unsupported

I don't know if all objects are declared with var. Just like the above Code, it is just a simple declaration of an object, and it has only one copy, you cannot use the new operation on an object like an instantiated class object, as in the comments section of the Code above. In this way, the reuse of objects is greatly limited. Unless the object you create requires only one copy, other methods are used to create the object.

The following describes how to access the attributes and methods of an object.
VaR myobj =
{
'Id': 1,
'Fun ': function (){
Document. writeln (this. ID + '-' + this. Name); // you can use the "object. Attribute" method to access
},
'Name': 'myobj ',
'Fun1': function (){
Document. writeln (this ['id'] + '+ this ['name']); // access data in a set
}
};
Myobj. Fun ();
Myobj. fun1 ();
// Result
// 1-myobj 1 + myobj

Ii. simulate a class with the function keyword

Use this in function to reference the current object and declare the attribute by assigning values to the attribute. If VaR is used to declare a variable, the variable is a local variable and can only be called in the class definition.

Function myclass (){
This. ID = 5;
This. Name = 'myclass ';
This. getname = function (){
Return this. Name;
}
}
VaR my = new myclass ();
Alert (My. ID );
Alert (My. getname ());
// Result
// 5
// Myclass

3. Create an object in the function body, declare its attributes, and then return

You can use the method of the first point to create an object in the function body, or use new object () to assign values to each attribute.

However, the objects created in this way do not have smart prompts in vs2008 SP1.
Function myclass (){
VaR OBJ =
{
'Id': 2,
'Name': 'myclass'
};
Return OBJ;
}
Function _ myclass (){
VaR OBJ = new object ();
OBJ. ID = 1;
OBJ. Name = '_ myclass ';
Return OBJ;
}
VaR my = new myclass ();
VaR _ My = new _ myclass ();
Alert (My. ID );
Alert (My. Name );
Alert (_ My. ID );
Alert (_ My. Name );

// Result
// 2
// Myclass
// 1
// _ Myclass

I. Define classes or objects
1. Factory method
Create an object car
VaR ocar = new object;
Ocar. color = "red ";
Ocar. Doors = 4;
Ocar. mpg = 23;
Ocar. showcolor = function (){
Alert (this. corlor );
};

Create multiple cars
Function createcar (color, doors, mpg ){
VaR tempcar = new object;
Tempcar. Color = color;
Tempcar. Doors = doors;
Tempcar. mpg = MPG;
Tempcar. showcolor = function (){
Alert (this. color)
};
Return tempcar;
}

VaR car1 = createcar ("red", 4, 23 );
VaR car2 = createcar ("blue", 3, 25 );
Car1.showcolor (); // outputs "red"
Car2.showcolor (); // outputs "blue"
In this example, a new showcolor () function is created every time the createcar () function is called, which means that each object has its own showcolor () version. In fact, each object shares the same function.
Some developers Define the object method outside the factory function and point to this method through the property to avoid this problem.
Function showcolor (){
Alert (this. Color );
}
Function createcar (color, doors, mpg ){
VaR tempcar = new object;
Tempcar. Color = color;
Tempcar. Doors = doors;
Tempcar. mpg = MPG;
Tempcar. showcolor = showcolor;
Return tempcar;
}

VaR car1 = createcar ("red", 4, 23 );
VaR car2 = createcar ("blue", 3, 25 );
Car1.showcolor (); // outputs "red"
Car2.showcolor (); // outputs "blue"
In terms of functions, this solves the problem of repeatedly creating function objects, but this function does not look like an object method. All these problems lead to the emergence of constructors defined by developers.

2. constructor Method
Function car (scolor, idoors, impg ){
This. Color = scolor;
This. Doors = idoors;
This. mpg = impg;
This. showcolor = function (){
Alert (this. color)
};
}

VaR ocar1 = new car ("red", 4, 23 );
VaR ocar2 = new car ("blue", 3, 25 );
Ocar1.showcolor (); // outputs "red"
Ocar2.showcolor (); // outputs "blue"
Just like a factory function, constructor will repeatedly generate a function and create an independent function version for each object. However, you can also use an external function to override the constructor. Likewise, this method has no meaning in semantics.

3. Prototype
Function car (){
}
Car. Prototype. color = "red ";
Car. Prototype. Doors = 4;
Car. Prototype. mpg = 23;
Car. Prototype. showcolor = function (){
Alert (this. Color );
}

VaR ocar1 = new car ();
VaR ocar2 = new car ();
It solves the two problems existing in the previous two methods. But it is not satisfactory. First, this constructor has no parameters. When using the prototype method, the parameter initialization attribute value cannot be passed through the constructor. This is annoying, but it is not complete yet. The real problem occurs when the property points to an object rather than a function. Consider the following example:
Function car (){
}
Car. Prototype. color = "red ";
Car. Prototype. Doors = 4;
Car. Prototype. mpg = 23;
Car. Prototype. Drivers = new array ("Mike", "Sue ");
Car. Prototype. showcolor = function (){
Alert (this. Color );
}

VaR ocar1 = new car ();
VaR ocar2 = new car ();
Ocar1.drivers. Push ("Matt ");
Alert (ocar1.drivers); // outputs "Mike, Sue, Matt"
Alert (ocar2.drivers); // outputs "Mike, Sue, Matt"

4. Mixed Constructors/prototype
Function car (scolor, idoors, impg ){
This. Color = scolor;
This. Doors = idoors;
This. mpg = impg;
This. Drivers = new array ("Mike", "Sue ");
}

Car. Prototype. showcolor = function (){
Alert (this. Color );
};

VaR ocar1 = new car ("red", 4, 23 );
VaR ocar2 = new car ("blue", 3, 25 );

Ocar1.drivers. Push ("Matt ");

Alert (ocar1.drivers); // outputs "Mike, Sue, Matt"
Alert (ocar2.drivers); // outputs "Mike, Sue"
Now it is more like creating a common object. All non-function properties are created in the constructor, which means that the default value of the property is assigned to the constructor parameters. Because only one instance of the showcolor () function is created, there is no memory waste.

5. Dynamic Prototype Method
Function car (scolor, idoors, impg ){
This. Color = scolor;
This. Doors = idoors;
This. mpg = impg;
This. Drivers = new array ("Mike", "Sue ");

If (typeof car. _ initialized = "undefined "){

Car. Prototype. showcolor = function (){
Alert (this. Color );
};
Car. _ initialized = true;
}
}

VaR ocar1 = new car ("red", 4, 23 );
VaR ocar2 = new car ("blue", 3, 25 );

Ocar1.drivers. Push ("Matt ");

Alert (ocar1.drivers); // outputs "Mike, Sue, Matt"
Alert (ocar2.drivers); // outputs "Mike, Sue"
The basic idea of the dynamic prototype method is the same as that of the mixed constructor/prototype method. That is, the non-function attributes are defined in the constructor, while the function attributes are defined using the prototype attributes. The only difference is that the location of the object method is assigned.

6. Hybrid Factory
This method is usually a work und when the previous method cannot be applied. The objective is to create a pseudo constructor and return only new instances of another object.
Function car (){
VaR tempcar = new object;
Tempcar. color = "red ";
Tempcar. Doors = 4;
Tempcar. mpg = 23;
Tempcar. showcolor = function (){
Alert (this. color)
};
Return tempcar;
}
Unlike the classic method, this method uses the new operator to make it look like a real constructor.

7. which method is used?
As mentioned above, the most widely used method is the hybrid constructor/prototype method. In addition, the dynamic prototype method is also popular, which is equivalent to the former in terms of functionality. either of the two methods can be used.

Ii. Modify objects
1. Create a New Method
You can use the prototype attribute to define new methods for any existing class, just like processing your own class.
Example:
Array. Prototype. indexof = function (vitem ){
For (VAR I = 0; I <this. length; I ++ ){
If (vitem = This [I]) {
Return I;
}
}
Retunr-1;
}
Finally, to add a new method to each local object in ecmascript, you must define it on the prototype attribute of the object.

2. Redefinition of existing methods
Just like defining new methods for your own classes, you can also redefine existing methods. The function name is just a pointer to the function, so you can easily point it to other functions.
For example
Function. Prototype. tostring = function (){
Return "function code hidden ";
}
Function sayhi (){
Alert ("hi ");
}
Alert (sayhi. tostring (); // outputs "function code hidden"

Class-class Creation
The class declares a new class in JavaScript and instantiates this class through the constructor. By using class. create () method. You actually declare a new class and define an initialize () method as the constructor, once you implement this method in the prototype of the declared class, you can use the new operator to create and instantiate a class.

Knowledge prepare-knowledge preparation
In JavaScript, When you define a new function, you actually declare a new class, and the function itself is equivalent to the class constructor. The following code shows you two different ways to create a new person class, and the definition of person. Prototype follows the definition of the function.

VaR person = function (name) {// an anonymous function, which is assigned to a person variable. At this time, person becomes a class.
This. Name = Name;
}

Function person (name) {// define a function called person to represent the person class.
This. Name = Name;
}

Person. Prototype = {// define the prototype field of person
Printname: function () {// defines a print function
Alert (this. Name );
}
}

After you declare a class through the function method, You Can instantiate this class through the new operator. In this way, you can call the member functions of the class to complete your logic.
VaR person = new person ("Joe Smith"); // use the new operator to create an instance of person and assign it to the variable "person"
Person. printname (); // person can be considered as an instance reference. Therefore, you can use this reference to call the member functions in the person class.

Let's summarize the entire process and steps for creating a new class instance:

1. Declare a new class by defining a function (anonymous or real-name.
2. If necessary, define the prototype field of the new class.
3. Use the new operator to keep up with the function you define to create an instance of a new class. Once the Javascript compiler encounters the new operator, it actually creates an empty class instance variable.
4. Copy all attributes and methods in the prototype field of the class to the new instance, and point all this pointers in the member functions to the newly created instance.
5. Next, execute the function that follows the new operator.
6. When you execute this function, if you try to assign a value to a non-existent attribute, the Javascript compiler will automatically create this attribute for you within the scope of this instance.
7. After the function is executed, return the instance after initialization.

In prototype, using a class object, you can declare a new object in a simple way. By using class. create (), prototype creates a default constructor initialize () for you. Once you implement this function, you can create an instance of a new class in a way similar to the constructor in Java.

Source view-source code parsing
VaR class = {// Global static class, used to declare a new class and provide support for constructors
Create: function (){
Return function () {// returns a function, representing the constructor of the newly declared class
// A function named initialize will be implemented by this class as a class Constructor
This. Initialize. Apply (this, arguments); // The initialize function will be called and executed when you instantiate a variable (step 1 in the above 7 steps)
}
}
}

Field & function reference-attribute method Overview
Class (static)

Method/Property
Kind
Arguments
Description
 
Create ()
Static Method
/
Declares a new class and provides support for a constructor named initialize.
 
Analysis & usage-analysis and usage

Through the class, you can easily create a new class using the constructor method, which may be more acceptable to Java programmers. Below we list the differences between Java and JavaScript declarations and the Code for creating a new class. We can see that they are so similar:

VaR person = Class. Create (); // class declaration | public class person {// class declaration
Person. Prototype = {| private string name;

Initialize: function (name) {// constructor | public person (string name) {// Constructor

This. Name = Name; | this. Name = Name;

} |}

Printname: function () {// member function | public void printname () {// member function

Alert (this. Name); | system. Out. println (name );

} |}

} |}

VaR person = new person ("Joe Smith"); // create an instance | person = new person ("Joe Smith"); // create an instance

Person. printname (); // function call | person. printname (); // function call

_______________ The source code of an instance ___________________________________________________________

VaR talent = {};

/**
* This code is taken from the Internet and the website cannot be found.
*/
// Create a context for self-executed anonymous functions to avoid introducing global variables
(Function (){
// The initializing variable is used to indicate whether the current class is being created,
//-During the class creation stage, the original method init cannot be called.
//-We have elaborated on this issue in the third article in this series.
// Fntest is a regular expression. The possible value is/\ B _super \ B/or /.*/)
//-Test/XYZ/. Test (function () {xyz;}) to check whether the browser supports the function as the test parameter.
//-However, I tested ie7.0, chrome2.0, and ff3.5. True is returned for all tests.
//-So I think it is also true to assign a value to fntest in most cases: fntest =/\ B _super \ B /;
VaR initializing = false, fntest =/XYZ/. Test (function (){
XYZ;
})? /\ B _super \ B /:/.*/;
// Base class Constructor
// This is a window, so the entire code Segment opens a window to the outside world-window. Class
This. Talent. Class = function (){
};
// Inheritance Method Definition
Talent. Class. Extend = function (PROP ){
// This is a confusing place. Do you still remember what I mentioned in the second article in this series?
//-This is not defined, but depends on how the function is called.
//-We already know that extend must be called as a method instead of a constructor.
//-So here this points not to the object, but to the function (that is, the class), so this. prototype is the prototype object of the parent class.
//-Note: _ super points to the prototype object of the parent class. We will encounter this variable multiple times in the subsequent code.
VaR _ super = This. Prototype;
// Inherit by pointing the subclass prototype to an instance object of the parent class
//-Note: This is a base class Constructor (that is, class)
Initializing = true;
VaR prototype = new this ();
Initializing = false;
// I think this code has been optimized by the author, so it is very hard to read. I will explain it later.
For (VAR name in prop ){
Prototype [name] = typeof prop [name] = "function"
& Typeof _ super [name] = "function"
& Fntest. Test (prop [name])? (Function (name, FN ){
Return function (){
VaR TMP = This. _ super;
This. _ super = _ super [name];
VaR ret = fn. Apply (this, arguments );
This. _ super = TMP;
Return ret;
};
}) (Name, prop [name]): prop [name];
}
// This area shows that resig is a good disguise.
//-It is confusing to use a local variable with the same name to overwrite the global variable.
//-You can use another name, such as function f (), to replace function class ()
//-Note: The class here is not the base class constructor defined in the outermost layer.
Function class (){
// Call the prototype method init during class instantiation
If (! Initializing & this. init)
This. init. Apply (this, arguments );
}
// Prototype of the subclass points to the instance of the parent class (the key to inheritance)
Class. Prototype = prototype;
// Fixed the constructor pointing error.
Class. constructor = Class;
// Subclass automatically obtains the extend method. Arguments. callee points to the currently executed function.
Class. Extend = arguments. callee;
Return class;
};
})();

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.