JavaScript is essentially a functional programming language and a descendant of Lisp. At the same time, it adds elements of object-oriented programming and abandons some difficult elements of functional languages.
There is no doubt that functional programming languages can realize object-oriented programming. The Curry method can realize the simulation of classes and objects. But JavaScript provides another way to implement OOP: prototypal inheritance.
Therefore, JavaScript implements object-oriented programming and general functional programming languages are still different.
In this article, I will introduce to you how to implement single inheritance and multiple inheritance in JavaScript.
Using prototypes to implement single inheritance:
There are many JavaScript libraries that provide some functions to help implement single inheritance. But in fact, JavaScript itself provides a method of prototypal inheritance. Therefore, there is no need to provide a specific method to implement it, and single inheritance can be achieved by simply using JavaScript code.
However, the prototypal inheritance method provided by JavaScript is easy to make mistakes. Let me show you how to implement prototypal inheritance concisely and clearly.
Assume that MyB inherits the MyA class, then the code is as follows:
function MyA(){
if(MyA.prototype.baseClass!==undefined){
MyA.prototype.baseClass.call(this);
}
...General code
}
function MyB(){
if(MyB.prototype.baseClass!==undefined){
MyB.prototype.baseClass.call(this);
}
...General code
}
MyB.prototype=new MyA();
MyB.prototype.baseClass=MyB.prototype.constructor;// Use baseClass to reference // the constructor function of the base class.
MyB.prototype.constructor=MyB;//Restore the constructor attribute of the subclass and use this attribute to determine the type of the object in the future.
var myA=new MyA();
var myB=new MyB();
In the above javascript code , I added this piece of code to each constructor:
if(ClassName.prototype.baseClass!==undefined){
ClassName.prototype.baseClass.call(this) ;
}
This code looks for the baseClass method in the prototype, and if there is one, calls it.
In the later implementation of prototypal inheritance, I created the baseClass attribute for the subclass, and its value is the constructor of the base class. Therefore, as long as I write the code the way I do, I guarantee that the base class's constructor will be executed when the subclass constructs an instance.
Now, if the MyA class inherits the Base class, you only need to add 3 lines of prototype inheritance code:
MyA.prototype=new Base();
MyA .prototype.baseClass= MyA.prototype.constructor; //Use baseClass to reference // the constructor function of the base class.
MyA.prototype.constructor= MyA;//Restore the constructor attribute of the subclass and use this attribute to determine the type of the object in the future.
There is no need to modify the code of the MyA class itself, instances of the MyA class and its subclass MyB class can be executed correctly.
Inheritance implemented by those JavaScript libraries requires modification of base classes such as Object and Function, which can easily cause conflicts. There are also some methods. Every time you implement inheritance, you must manually modify the constructor of the subclass so that the constructor can correctly call the constructor of the base class.
The method provided above to write JavaScript code solves these problems well.
Use Mixin (mixin) to achieve multiple inheritance
JavaScript itself does not provide a mechanism for multiple inheritance, but we can use the Mixin (mixin) technique to achieve the effect of multiple inheritance.
The following is the Mixin helper method I wrote, which can dynamically add attributes to classes and objects.
1, copyClassPrototypeProperties copies the prototype properties of the class
/**
* Copies all attributes on the prototype of the source class to the target object. The first parameter is a boolean value, indicating whether to override the attributes of the prototype of the target class
*/
function copyClassPrototypeProperties(isOverride,receivingClass,givingClass){
if(arguments.length>3){
for(var i=3;i
receivingClass.prototype[arguments[i]]= givingClass.prototype[arguments[i]];
}
}else if(arguments.length==3){
for(var name in givingClass.prototype) {
if(isOverride){
receivingClass.prototype[name]=givingClass.prototype[name];
}else{
//Do not override
if(!receivingClass.prototype[name]){
receivingClass.prototype[name]=givingClass.prototype[name];
}
}
}
}else{
throw "Please give 3 arguments at least!";
}
}
2, copyObjectProperties copies the properties of the object
/*
* Copies all the properties of the source object to the target object. The first parameter is a boolean value. Indicates whether to override the properties of the target object
*/
function copyObjectProperties(isOverride,receivingObject,givingObject){
if(arguments.length>3){
for(var i=3;i
receivingObject[arguments[i]]=givingObject[arguments[i]];
}
}else if(arguments.length==3){
for(var name in givingObject){
if(isOverride){
receivingObject[name] =givingObject[name];
}else{
//Do not override
if(!receivingObject[name]){
receivingObject[name]=givingObject[name];
}
}
}
}else{
throw "Please give 3 arguments at least!";
}
}
3, copyProperties copies properties to object
/*
* Copies properties to target In an object, there can be any number of properties, and they can be arrays.
*/
function copyProperties(target){
for (var i=1;i
if(arguments[i].constructor===Array){
copyArrayProperties(target,arguments[i]);
}else{
for (var name in arguments[i]){
target[name] =arguments[i][name];
}
}
}
}
/*
* Copy the properties in array format to the target object. Users should not call this method directly
*/
function copyArrayProperties(target,arrayArg){
for(var i=0;i
copyArrayProperties(target,arrayArg[i] );
}else{
for(var name in arrayArg[i]){
target[name] =arrayArg[i][name];
}
}
}
}
PS: Currently I am planning to write a JavaScript library to provide many functions, including UI components, with concise code.