Home  >  Article  >  Web Front-end  >  Let JavaScript easily support function overloading (Part 1 - Design)_javascript skills

Let JavaScript easily support function overloading (Part 1 - Design)_javascript skills

WBOY
WBOYOriginal
2016-05-16 18:48:38933browse
Does JavaScript support overloading?
Does JavaScript support function overloading? You can say you don't support it, you can also say you support it. It is said that it is not supported because JavaScript cannot directly write multiple functions with the same name and let the compiler determine which overload corresponds to a certain call, like other languages ​​that natively support function overloading. It is said to be supported because JavaScript functions do not impose any restrictions on the parameter list, and support for function overloading can be simulated within the function.
In fact, in many well-known open source libraries, we can see the design of internal simulation overload support within functions. For example, jQuery's jQuery.extend method determines whether the optional parameter exists through the parameter type. If it does not exist, the parameter is shifted to ensure that the subsequent logic runs correctly. I believe many people have written similar code when writing JavaScript, in order to provide a simple call entry (or multiple) for feature-rich functions.
However, there is a fundamental problem with the seeding method, that is, it violates the DRY principle. Each function that supports overloading has an extra piece of code inside, which is used to handle overloading based on the number of parameters and parameter types. These codes imply repeated logic, but each piece of code is different when written. In addition, these codes are not easy to maintain, because when reading the code, you cannot tell at a glance what the several overloading methods supported by the function are, and it is naturally difficult to maintain the overloading.
DSL describing overloaded portals
I would like to be able to describe overloaded portals in JavaScript in a simple way. It's best to use function signatures to distinguish overload entries as in other languages, because I think function signatures are the best DSL for this. The overloaded entry description DSL that I imagine is most consistent with JavaScript syntax should look like this:
Copy code The code is 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 corresponding function body, sum The function call should look like this:
sum(1, 2);
sum(1, 2, 3);
The above code seems to me very clear and easy to maintain - you You can see the signature of the reload entry at a glance, and it is very easy to modify or add the reload entry. But we encountered a problem, that is, functions in JavaScript cannot be new, and objects obtained through new Overload() must not be called. For this reason, we can only make Overload a static class, and the static method returns Function instance:
Copy code The code is 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 overloaded entry support
Imagine what common JavaScript function entries cannot be described by the above DSL? There are two types that I know of:
Arbitrary type parameters
Suppose we want to write an each function. For Array, we iterate its subscripts, and for other types, we iterate all its members. The entrances of these two functions are: How to declare parameter list? If using C#, we would describe the two function entrances like this:
void Each(IEnumerable iterator) { }
void Each(object iterator) { }
However, in JavaScript, Object is not the base class of all types , (100) The result of instanceof Object is false, so we cannot use Object to refer to any type, and must introduce a new symbol to refer to any type. Considering that this symbol should not conflict with any possible class names, I chose to use "*" to represent any type. The JavaScript corresponding to the above C# code should look like this:
Copy the code The code is as follows:

var each = Overload
.add("Array",
function(array) { })
.add("*",
function(object) { });

Any number of parameters
In JavaScript functions, it is a very common requirement to support any number of parameters. I believe it is used much more than the params keyword in C#. This cannot be described in the rules we formulated before, so we have to introduce a symbol that does not conflict with the class name to represent params in C#. I chose to use "..." to represent params, which means that any number of parameters present here are acceptable. Let's see how the overload of jQuery.extend should be described:
Copy the code The code is as follows:

var extend = Overload
.add("*, ...",
function(target) { })
.add("Boolean, *, ...",
function(deep, target) { });

Summary
In this article, we try to design a method that is suitable for JavaScript and easy to read Easy-to-maintain function overloading. In the next article, we will try to write the Overload class to implement this design.
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn