Make JavaScript easily support function overloading (Part 2-Implementation)

Source: Internet
Author: User

Recognize text signatures
Let's review the previous article. Article Overload case mentioned in:

CopyCode The Code is as follows: var extend = overload
. Add ("*,...",
Function (target ){})
. Add ("Boolean ,*,...",
Function (deep, target ){});

We allow the user to enter a string to indicate an overloaded signature. When a user calls a function, we need to compare the parameter type with each parameter type in the signature with the parameter instance input by the user. Therefore, we need to convert the string to a type array first. That is to say, the string "Boolean, number, array" should be converted to an array [Boolean, number, array].

Before conversion, we must consider processing two special types: "*" representing any type and "..." representing any number "...". We can define two proprietary types for them for special Compatibility processing within overload:

Copy code The Code is as follows: overload. Any = function (){};
Overload. More = function (){};

After the two types are available, the string "Boolean, *,..." will be correctly converted to the array [Boolean, overload. Any, overload. More]. Because both overload. Any and overload. More are functions, they can also be considered as types.

After these two types are correctly processed, we can start to write the Conversion Function for recognizing text signatures:

Copy code The Code is as follows: if (signature. Replace (/(^ \ s + | \ s + $)/ig, "") = ""){
Signature = [];
} Else {
Signature = signature. Split (",");
For (VAR I = 0; I <signature. length; I ++ ){
VaR typeexpression = signature [I]. Replace (/(^ \ s + | \ s + $)/ig ,"");
VaR type = NULL;
If (typeexpression = "*"){
Type = overload. Any;
} Else if (typeexpression = "..."){
Type = overload. More;
} Else {
Type = eval ("(" + typeexpression + ")");
}
Signature [I] = type;
}
}

I think this code is quite easy to understand, so I will not explain it again. When I wrote this code for the first time, I forgot to write the first if. As a result, the blank signature string "" cannot be correctly recognized as a blank signature array [], fortunately, my unit test code immediately discovered this defect. It seems that it is very important to compile the unit test code.

Matching function Signature
After we get the type array of the function signature, we can use it to match the input parameter's instance array to find the correct overload. Before discussing how to match a function signature, let's take a look at how C # Or VB. NET languages handle function reload matching. In general, the process of performing function reload matching in a language is like this:

Parameter count-overload with Incorrect Parameter count will be excluded
Parameter type-if the parameter type cannot be implicitly converted to the signature type, it will be excluded.
Matching count-after the exclusion is completed, the remaining number of matching signatures varies with different processing methods.
0 matches-no matching hits
One match-this is the matching of hits
Two or more matches-if you can find the best match among these matches, it will hit the best match; otherwise, it will not hit any match.
In this section, we first take the first two steps in the process to remove the signature with the number of parameters or different parameter types:

Copy code Code: var matchsignature = function (argumentsarray, signature ){
If (argumentsarray. Length <signature. Length ){
Return false;
} Else if (argumentsarray. length> signature. Length &&! Signature. More ){
Return false;
}
For (VAR I = 0; I <signature. length; I ++ ){
If (! (Signature [I] = overload. Any
| Argumentsarray [I] instanceof signature [I]
| Argumentsarray [I]. constructor = signature [I]) {
Return false;
}
}
Return true;
};

In order to compare the length, we need to perform some special processing on the "..." that represents the number of parameters outside this function:

Copy code The Code is as follows: if (signature [signature. Length-1] = overload. More ){
Signature. Length = signature. Length-1;
Signature. More = true;
}

This piece of code will be integrated into the end of the transformation function in section 1, so that the matchsignature function can easily determine whether the parameter and signature match. Ideally, we match 0 or 1 overload for the input parameter type, so that we can easily determine which overload is hit. However, if there are two or more reload matches, we need to select an optimal one. This is what we will discuss in the next section.

Process multiple matches
For more information about how C # selects a more matched overload from multiple matches, see section C # language specification. I think the problem can be explained through three simple examples:

Copy code Code: Long sum (int x, int y) {return X + Y ;}
Long sum (long X, long y) {return X + Y ;}
Sum (0, 1 );

Since the two parameters 0 and 1 are understood as the int type by the compiler, no type conversion is required for the 1st overload, and both of them need to be converted to the 2nd overload, therefore, the 1st overload is better.

Copy code Code: Long sum (int x, long y) {return X + Y ;}
Long sum (long X, int y) {return X + Y ;}
Sum (0, 1 );

Among the 1st parameters, the 1st overload is better; among the 2nd parameters, the 2nd overload is better. In this case, any overload is no better than the other, and an error is returned if a better overloaded compiler is not found.

Copy code Code: Long sum (int x, int y) {return X + Y ;}
Long sum (int x, long y) {return X + Y ;}
Long sum (long X, int y) {return X + Y ;}
Sum (0, 1 );

On the 1st parameters, the 1st overload is better than the 3rd overload, and the 2nd overload is no different. On the 2nd parameters, the 1st overload is better than the 2nd overload, and the 3rd overload is no different. Although there are no advantages or disadvantages for the 2nd or 3rd reloads, we can determine that the 1st reloads are better than them, so the compiler chooses 1st reloads.

Suppose we have a comparison function of overloadcomparator to compare the advantages and disadvantages of any two signatures. Do we need to compare the two signatures in order to find the optimal overload? In fact, this is not necessary. We can use the sort method of array to call overloadcomparator for sorting. After sorting, we can verify the relationship between the first two names. If this is the same, it does not hit any one. If there is a sequence, it hits the first one.

The specific overloadcomparator code is not provided here. It depends on another comparison function called inheritancecomparator to compare the parameter types of the two signatures. Which of the following is more accurate to the actual input parameter types, it uses a clever method to determine whether two types are inherited, and who inherits from them.

Summary
Now we have a JavaScript function overload library. For the complete code, see: function overload library overload. We hope this library can help you improve the readability of JavaScript code and reduce the maintenance cost of large Ajax projects.

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.