Class inheritance _javascript techniques in JavaScript

Source: Internet
Author: User
Tags extend inheritance instance method

JavaScript inheritance

Douglascrockford
Www.crockford.com

And you are so clever and classless and
--john Lennon

JavaScript a class-oriented, object-oriented language that uses prototype inheritance to replace class inheritance. This may be a bit confusing for programmers trained in traditional object-oriented languages such as C + + and Java. JavaScript's prototype inheritance has more powerful expressiveness than class inheritance, so let's look at it now.

"

Java

JavaScript

Strong type

Weak type

Static

Dynamic

Class-based

Based on prototypes

Class

Function

Constructor

td>
Function

Method

Function

But first, why do we care so much about inheritance? There are two main reasons. The first one is of type advantage. We want the language system to automatically make conversions castof similar type references. Small-type security can be obtained from a type system that requires a program to be displayed to transform object references. This is the key point of a strongly typed language, but it is irrelevant for a weakly typed language like JavaScript, and class references in JavaScript do not need to be cast.

The second reason is to reuse the code. It is often found in programs that many objects will implement the same methods. Class makes it possible to establish an object in a single set of definitions. It is also common for objects to contain objects that are also contained in other objects, but the difference is only a small number of methods added or modified. Class inheritance is useful for this, but prototype inheritance is even more useful.

To show this, we're going to introduce a little "dessert" where we can write code like a regular class language. We will then show some useful patterns that are not available in the class language. Finally, we will explain these "desserts".
Class inheritance
First, we create a Parenizor class that has the get and set methods of member value, and a ToString method that wraps value in parentheses.

Copy Code code as follows:

function Parenizor (value) {
This.setvalue (value);
}
Parenizor.method (' SetValue ', function (value) {
This.value = value;
return this;
});
Parenizor.method (' GetValue ', function () {
return this.value;
});
Parenizor.method (' toString ', function () {
Return ' (' + this.getvalue () + ') ';
});

This syntax may be of little use, but it is easy to see the form of the class. Method methods accept a method name and a function and place them in a class as a public method.
Now we can write
Copy Code code as follows:

Myparenizor = new Parenizor (0);
myString = Myparenizor.tostring ();

As expected, mystring is "(0)".
Now we're going to build another class that inherits from Parenizor, and it's basically the same except the ToString method will produce " -0-" if value is 0 or empty.
Copy Code code as follows:

function Zparenizor (value) {
This.setvalue (value);
}
Zparenizor.inherits (Parenizor);
Zparenizor.method ("e;tostring" E;, function () {
if (This.getvalue ()) {
Return This.uber (' toString ');
}
return " -0-";
});

The Inherits method is similar to the Java extends. The Uber method is similar to the Java super. It makes a method call the method of the parent class (changing the name to avoid conflicts with reserved words).
We can write this.
Copy Code code as follows:

Myzparenizor = new Zparenizor (0);
myString = Myzparenizor.tostring ();

This time, mystring is " -0-".
JavaScript does not have a class, but we can program to do that.
Multiple inheritance
By manipulating the prototype object of a function, we can implement multiple inheritance. Mixed multiple inheritance is difficult to implement and may be at risk of name collisions. We can implement mixed multiple inheritance in JavaScript, but in this case we'll use a more canonical form called the Swiss successor Swissi Nheritance.
Suppose there is a numbervalue class that has a SetValue method to check whether value is a number within a specified range and throws an exception at the appropriate time. We only want its SetValue and SetRange method to give our Zparenizor. Of course we don't want its ToString method. In this way, we write:
Copy Code code as follows:

Zparenizor.swiss (Numbervalue, ' setValue ', ' setRange ');

This will only add the required method.
Parasitic inheritance
This is another way to write Zparenizor classes. Instead of inheriting from Parenizor, it writes a constructor that calls the Parenizor constructor and returns the result to the result modification. This constructor adds a privileged method rather than a public method.
Copy Code code as follows:

function ZParenizor2 (value) {
var self = new Parenizor (value);
self.tostring = function () {
if (This.getvalue ()) {
Return This.uber (' toString ');
}
Return " -0-"
};
return self;
}

Class inheritance is a kind of "is ..." relationship, and parasitic inheritance is a about "the original is ... And now is the relationship of .... Constructors play a large number of roles in the construction of objects. Note that the Uber (instead of the Super keyword) is still valid for the privileged method.
Class extension
The dynamic nature of JavaScript allows us to add or replace methods for an existing class. We can call the method at any time. We can extend a class at any time. Inheritance is not the way. So we call this a "class extension" to avoid the extends── of Java, but not the same thing--confusing.
Object extension
In static object-oriented languages, if you want one object to be different from another, you must create a new class. But in JavaScript, you can add a method to a separate object without creating a new class. This will have a huge amount of energy because you can write as few classes as possible, and classes can be easier to write. Think of JavaScript objects like a hash table. You can add a new value at any time. If this value is a function, then he will become a method.
So in the above example, I do not need the Zparenizor class at all. All I have to do is simply revise my example.
Copy Code code as follows:

Myparenizor = new Parenizor (0);
myparenizor.tostring = function () {
if (This.getvalue ()) {
Return This.uber (' toString ');
}
return " -0-";
};
myString = Myparenizor.tostring ();

We added a ToString method to the Myparenizor instance without using any inheritance. We can evolve a separate instance because the language is of no type.
Small dessert
For the above example to work, I wrote four "dessert" methods. First, you can add an instance method to a class by means of a method.
Copy Code code as follows:

Function.prototype.method = function (name, func) {
This.prototype[name] = func;
return this;
};

This will add a public method into the function.prototype so that all functions can be extended through the class. It takes a name and a function as an argument.
It returns this. When I write a method that does not return a value, I usually let it return this. This can form a chained statement.
The following is the Inherits method, which indicates that a class is inherited from another class. It must be defined after all two classes are finished, but it is to be invoked before the method inherits.
Copy Code code as follows:

Function.method (' Inherits ', function (parent) {
var d = 0, p = (This.prototype = new parent ());
This.method (' Uber ', function uber (name) {
var F, r, T = d, v = parent.prototype;
if (t) {
while (t) {
v = v.constructor.prototype;
T-= 1;
}
f = v[name];
} else {
f = p[name];
if (f = = This[name]) {
f = v[name];
}
}
D + + 1;
R = f.apply (this, Array.prototype.slice.apply (arguments, [1]));
D-= 1;
return R;
});
return this;
});

Again, we extend the function class. We add an instance of the parent class and make it a new prototype. We also have to revise the constructor field, and we add the Uber method.
The Uber method will find a method in its own prototype. This is a case of parasitic inheritance or class expansion. If we are class inheritance, then we have to find the function in the prototype of parent. The return statement invokes the function's apply method to invoke the function, displaying the this and passing parameters. parameters, if any, can be obtained from the arguments array. Unfortunately, the arguments array is not really an array, so we have to use apply to invoke the slice method in the array.
Finally, the Swiss method
Copy Code code as follows:

Function.method (' Swiss ', function (parent) {
for (var i = 1; i < arguments.length i + + 1) {
var name = Arguments[i];
This.prototype[name] = Parent.prototype[name];
}
return this;
});

The Swiss method loops through each parameter. Each name, it copies the members of the parent's prototype into the prototype of the new class.
Summarize
JavaScript can be used like a class language, but it also has a very unique level of performance. We've seen class inheritance, Swiss inheritance, parasitic inheritance, class extensions, and object extensions. This series of code reuse patterns can come from a JavaScript language that has long been thought to be small and simple.
class objects belong to "hard". The only way to add a member to a "hard" object is to create a new class. In JavaScript, objects are "soft." To add members to a "soft" object, simply assign the value.
Because classes in JavaScript are so flexible, you may also think of more complex class inheritance. But deep inheritance is not appropriate. Shallow inheritance is more effective and easier to express.

Related Article

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.