Implement inheritance in Javascript
Author: Tudou Dad
Javascript scripting is a powerful object-oriented language. This article describes how to implement inheritance in JavaScript.
Prototype
JavaScript does not implement class inheritance, but it can be implemented through prototype. Each JavaScript class contains a prototype object. when accessing an object's attributes and methods, it first searches for the current object. If this property is defined in a javascript class, it is directly accessed. Otherwise, search from the prototype object of the class. If yes, access directly. Otherwise, search from the prototype object of the prototype, and so on. The prototype object is empty. In other words, the current object inherits all the attributes and methods of its prototype class.
However, a prototype object belongs to a class, and a class can create multiple objects. Therefore, reading and writing are different when accessing inherited attributes. When reading an inherited attribute, follow the steps described above to find the attribute. When writing an attribute, the data is copied from prototype to the current object. when reading the property again, access the attributes of the current object. This problem does not exist for methods.
Implement inheritance
The prototype of the Javascript class defaults to the object class. Therefore, all classes in Javascript inherit from the object class. We can modify the prototype attribute of a class so that it points to another object to implement inheritance. There are two methods to implement inheritance:
- Modifies the prototype attribute of a class to point to a parent class object.
- Modify the constructor attribute of the prototype object of a class and specify a constructor of the parent class for it.
The two methods are basically the same, but there are some differences. Code List 1 adopts the first method, and code list 2 adopts the second method.
// Define the base class shapefunction shape (x, y) {This. X = x; this. y = y; this. fromorigin = function () {// defines the return math method. SQRT (this. x * This. X + this. y * This. y);} // you can use this method/* shape. prototype. fromorigin = function () {return math. SQRT (this. x * This. X + this. y * This. y);} * // defines the subclass circlefunction circle (X, Y, R) {circle. prototype. constructor (x, y); // call the parent class constructor this. R = r;} circle. prototype = new shape (); // bind the parent object // test var c = new circle (5, 5, 10); print (c); C. X = 3; // modify the attribute C. y = 4; print (c); // print function print (c) {document. write ("circle. prototype. X = "+ circle. prototype. x, "<br/>"); document. write ("circle. prototype. y = "+ circle. prototype. y, "<br/>"); document. write ("C. X = "+ C. x, "<br/>"); document. write ("C. y = "+ C. y, "<br/>"); document. write ("C. R = "+ C. r, "<br/>"); document. write ("C. fromorigin () = "+ C. fromorigin (), "<br/>");} Listing 1: modifying the prototype attribute of a class
Output result;
Circle.prototype.x=5Circle.prototype.y=5c.x=5c.y=5c.r=10c.fromOrigin()=7.0710678118654755Circle.prototype.x=5Circle.prototype.y=5c.x=3c.y=4c.r=10c.fromOrigin()=5
In the above Code, use circle. Prototype = new shape (); to bind the parent object. The circle object contains all the attributes and methods of a shape.
In the first output, we created a circle object. In the circle constructor, we call the constructor of the parent shape class to initialize x and y in the shape. When accessing C. X, X of the Shape object referenced by circle. prototype is actually accessed.
In the second output, we modified the X and Y of the circle object. copy X and Y of the Shape object referenced by prototype to the Circle object. Modifying the circle object does not affect circle. the shape object referenced by prototype.
The fromorigin method can be specified either in the shape constructor or in shape. prototype.
// Define the base class shapefunction shape (x, y) {This. X = x; this. y = y; this. fromorigin = function () {// defines the return math method. SQRT (this. x * This. X + this. y * This. y);} // This method cannot be used/* shape. prototype. fromorigin = function () {return math. SQRT (this. x * This. X + this. y * This. y);} * // defines the subclass circlefunction circle (X, Y, R) {circle. prototype. constructor (x, y); // call the parent class constructor this. R = r;} circle. prototype. constructor = shape; // The constructor bound to prototype is shape (x, y) // test var c = new circle (5, 5, 10); print (C ); c. X = 3; // modify the attribute C. y = 4; print (c); // print function print (c) {document. write ("circle. prototype. X = "+ circle. prototype. x, "<br/>"); document. write ("circle. prototype. y = "+ circle. prototype. y, "<br/>"); document. write ("C. X = "+ C. x, "<br/>"); document. write ("C. y = "+ C. y, "<br/>"); document. write ("C. R = "+ C. r, "<br/>"); document. write ("C. fromorigin () = "+ C. fromorigin (), "<br/>"); // document. write (circle. prototype instanceof object);} Listing 2: modifying the constructor attribute of the prototype object of a class
The output result of Listing 2 is the same as that of Listing 1.
In the above Code, use circle. Prototype. constructor = shape; the constructor bound to prototype is shape (x, y ).
The fromorigin method can only be specified in the shape constructor. It cannot be specified in shape. prototype. The reason is circle. prototype. constructor = shape; only the specified circle. prototype constructor. The prototype object type of circle has not changed and is still the object type. the method of prototype binding is invisible to circle.
Conclusion
Javascript is an object-oriented language, although it does not seem obvious on the surface (top-level functions are global objects ). We can use prototype of the Javascript class to implement inheritance. The two methods and their nuances are mentioned in this article.
References
David Flanagan, javascript: the definitive guide, 4th edition, O 'Reilly, 2001.