does JavaScript support overloading?
Does JavaScript support function overloading? Can say not support, also can say support. It is not supported because JavaScript cannot write multiple functions of the same name directly as other native languages that support function overloading, allowing the compiler to determine which overload a call corresponds to. This is supported because JavaScript functions do not limit the argument list, and can simulate support for function overloading within the function.
In fact, in many well-known open source libraries, we can see the design of function internal simulation overload support. The Jquery.extend method of jquery, for example, is to determine whether an optional parameter exists through a parameter type and, if not, to shift the parameters to make sure that the logic behind it runs correctly. I believe a lot of people write JavaScript with similar code in order to provide one (or more) simple call entry for a feature-rich function.
But the fundamental problem with doing something is that it violates the dry principle. Each function that supports overloading has an extra piece of code that handles overloads based on the number of parameters and the type of parameter, which implicitly contains repetitive logic, but each paragraph is written differently. In addition, the code is not easy to maintain, because when reading code you can not see how many overloaded methods of function support, it is difficult to maintain the overload.
DSL that describes overloaded portals
I want to be able to describe overloaded portals in a simple way in JavaScript. It's best to use function signatures to differentiate overloaded portals as in other languages, because I think functional signatures are the best DSL in this area. I suppose the overloaded portal that fits the JavaScript syntax best describes a DSL that should be:
Copy Code code as follows:
var sum = new overload ();
Sum.add ("number, number",
function (x, y) {return x + y;});
Sum.add ("number, number, number",
function (x, y, z) {return x + y + z;});
After describing the overloaded entry and the corresponding function body, the call to the SUM function should be this way:
SUM (1, 2);
SUM (1, 2, 3);
The above code seems to me to be very clear and easy to maintain-you can see the signature of the overloaded entry at a glance, and it's easy to modify or increase the overload entry. But we have a problem, that is, the function in JavaScript is not new, the object obtained through new overload () must not be called, so we can only make overload into a static class, the static method returns the function instance:
Copy Code code as follows:
var sum = overload
. Add ("Number, number",
function (x, y) {return x + y;})
. Add ("number, number, number",
function (x, y, z) {return x + y + z;});
Necessary overload-Entry support
Imagine what common JavaScript function portals are not described with the above DSL? There are two kinds of what I know:
Any type of parameter
Suppose we want to write a each function, iterate over its subscript for the array, iterate over all its members for other types, and how are the argument lists of the two functions portals declared? If you use C #, we'll describe two function portals:
void each (IEnumerable iterator) {}
void each (object iterator) {}
However, in JavaScript, object is not all types of base class, (instanceof) The result of object is false, so we can not use object to refer to any type, we must introduce a new symbol to refer to any type. Considering that this symbol should not conflict with any class names that might exist, I chose "*" to represent any type. The corresponding javascript for the above C # code should be this way:
Copy Code code as follows:
var each = overload
. Add ("Array",
Function (array) {})
. Add ("*",
Function (object) {});
any number of parameters
In JavaScript functions, it is a common requirement to support any number of parameters, and it is believed that the usage rate is much more than the params keyword inside C #. This cannot be described in the rules we have made before, so we want to introduce a symbol that does not conflict with the class name to represent the params in C #. I chose to use "..." to denote params, which means that any number of parameters here are acceptable. Let's take a look at how the Jquery.extend overload should be described:
Copy Code code as follows:
var extend = overload
. Add ("*, ...",
function (target) {})
. Add ("Boolean, *, ...",
function (deep, target) {});
Summary
In this article, we try to design a function overload that is suitable for JavaScript and easy to read and maintain. In the next article, we will try to write the overload class to implement this design.