JavaScript-based OOP Programming
The simplest way to define an object
var car = {color:"red",drive:function() {alert(this.color + " car moved");}}
This method is not very useful because it creates a separate object, which has no connection with any common data structures. To create a second car instance, its structure must be redefined.
Create a new object using the constructor
function Car() {this.color = "red";this.drive = function(){alert(this.color + " car moved");}}var car = new Car();car.drive();
Each function in JavaScript has a property called prototype. If a function is used as a constructor, this property is automatically called by new to create a prototype of the object.
function Car() {this.color = "red";}Car.prototype.drive = function(){alert(this.color + " car moved");}var car = new Car();car.drive();
Any changes made to the prototype attribute can be applied to every object constructed through new Car (), whether it is created before or after the change. it is a Car. add a new function for prototype. for every object that shares the same prototype, this function can be used immediately, whether it is constructed before or after modification, as follows:
// Update the prototype function Car (color) {this. color = color;} Car. prototype. drive = function () {alert (this. color + "car is driving");} var car1 = new Car ("red"); alert (car1. _ proto _ = Car. prototype); // truecar1.drive (); // Add a new function Car for the prototype. prototype. stop = function () {alert (this. color + "car has stopped");} var car2 = new Car ("blue"); // share the Object alert (Object. getPrototypeOf (car1) === Object. getPrototypeOf (car2); // true // both objects can now access this new method car2.stop (); car1.stop ();
An important feature of object-oriented is inheritance. Here we only need to introduce the inheritance through prototype chain.
// Inherited basic settings function Car (color) {this. color = color;} Car. prototype. drive = function () {alert (this. color + "car is driving");} Car. prototype. turn = function (direction) {alert (this. color + "car turns" + direction);} Car. prototype. stop = function () {alert (this. color + "car has stopped");} // fire truck function FirTruck () {} FirTruck. prototype. turnCannon = function (direction) {alert ("Cannon moves to the" + direction);} var truck = new FirTruck (); // because of Car. prototype is not in the prototype chain of the truck object. // Therefore, the move () method is not available in truck. move (); truck. turnCannon ("right ");
JavaScript has a special Object. create (proto, properties) method. Note: IE8 and below are not supported.
It can be used to create a new blank object and set its prototype to proto
Function Car (color) {this. color = color;} Car. prototype. move = function () {alert (this. color + "car is driving");} Car. prototype. turn = function (direction) {alert (this. color + "car turns" + direction);} Car. prototype. stop = function () {alert (this. color + "car has stopped");} if (! Object. create) {// compatibility handling FireTruck. prototype = Car. prototype;} else {FireTruck. prototype = Object. create (Car. prototype);} function FireTruck () {}// check, in case of // alert (Object. getPrototypeOf (FireTruck. prototype) = Car. prototype); // if it is true // the Car. prototype is added to FireTruck. prototype. turnCannon = function (direction) {alert ("Cannon moves to the" + direction);} var truck = new FireTruck (); // now you can work because Car. prototype is already in the prototype chain of the truck object. move (); truck. turnCannon ("right ");
Code can run, but its output still has some problems.
True
Undefined car is driving
Cannon moves to the right
The color of a Car can now be set using the Car constructor. the constructor itself is not executed, so its color is undefined. this problem is well solved. Modify the FireTruck constructor and add a call to the Car constructor, so that the Car can initialize its own object variable.
function FireTruck() {Car.call(this, "red");}
Run this code again and appreciate the correct output.
Even if the code runs successfully, there is still a small problem to be solved. when a new function is created, its prototype attribute is not empty. it has an attribute called constructor that will reference the function itself.
FireTruck. prototype = Object. create (Car. prototype );
This attribute is lost because the new object does not have its own properties. You can pass the lost property as the second parameter to create
FireTruck. prototype = Object. create (Car. prototype, {constructor: {value: FireTruck, // and FireTruck. prototype. like constructor, enumerable: false, writable: true, retriable: true }});
The constructor here is not a common attribute. when the key value of an object is recycled, it does not appear, but can be accessed directly by name. you can pass the attribute "descriptor" to the second parameter of create () to achieve the same effect.
The descriptor has the following fields:
Value: Initial value
Enumerable: if the property is displayed in the Object property list, in a loop like for... in or Object. keys
Writable: If the attribute can be assigned a different value
Retriable: true if the rule defined by the descriptor can be modified or its attributes can be deleted.
In this way, the real constructor behavior can be imitated.
Inheritance EXAMPLE OF THE FINAL VERSION
Function extend (subConstructor, superConstructor) {if (! Object. create) {subConstructor. prototype = superConstructor. prototype; subConstructor. constructor = {value: FireTruck, // and FireTruck. prototype. like constructor, enumerable: false, writable: true, retriable: true} else {subConstructor. prototype = Object. create (superConstructor. prototype, {constructor: {value: FireTruck, // and FireTruck. prototype. like constructor, enumerable: false, writable: true, retriable: true }}) ;}} function Car (color) {this. color = color;} Car. prototype. move = function () {alert (this. color + "car is driving");} Car. prototype. turn = function (direction) {alert (this. color + "car turns" + direction);} Car. prototype. stop = function () {alert (this. color + "car has stopped");} function FireTruck () {Car. call (this, "red");} extend (FireTruck, Car); FireTruck. prototype. turnCannon = function (direction) {alert ("Cannon moves to the" + direction);} var truck = new FireTruck (); truck. move (); truck. turnCannon ("right ");