It just so happened that infinte student proposed "More elegant compatibility" which is actually related to this problem (we will see later)
In the Helper of Function in youa's script library, add Supports overloaded pattern matching
/**
* Function parameter overload method overload, which performs pattern matching on function parameters. The default dispatcher supports * and... and ?, "*" represents a parameter of any type, "..." represents multiple parameters of any type, "?" is generally used in ",?..." represents 0 or any number of parameters
* @method overload
* @static
* @optional {dispatcher} is used to match the function responsible for dispatching parameters
* @param {func_maps} accepts calls based on matching Function list
* @return {function} Overloaded function
*/
overload: function(dispatcher, func_maps) {
if (! (dispatcher instanceof Function)) {
func_maps = dispatcher;
dispatcher = function(args) {
var ret = [];
return map(args, function(o) {return getType(o)}).join();
}
}
return function() {
var key = dispatcher([].slice.apply(arguments));
for (var i in func_maps) {
var pattern = new RegExp("^" i.replace("*", "[^ ,]*").replace("...", ".*") "$");
if (pattern.test(key)) {
return func_maps[i].apply(this, arguments);
}
}
};
},
FunctionH.overload includes two parameters, one is the dispatcher function responsible for processing the matching conditions (optional province), and the other is a set of function mapping tables. The default dispatcher function generates a string based on the actual parameter type called. For example, the three parameters called are 10, "a", and [1,2] will generate "number" , string, array". When implementing pattern matching, a regular expression will be generated based on each "key" of the function mapping table. This regular expression will be used to match the return value of the dispatcher function. If it matches, the corresponding key will be called. processing function, otherwise match the next key in sequence, for example:
getEx: function(obj, prop, returnJson) {
var ret, propType = ObjectH.getType(prop);
if (propType == 'array') {
if (returnJson) {
ret = {};
for (var i = 0; i & lt; prop.length; i ) {
ret[prop[i]] = ObjectH.getEx(obj, prop[i]);
}
} else {
//getEx(obj, props)
ret = [];
for (var i = 0; i & lt; prop.length; i ) {
ret[i] = ObjectH.getEx(obj, prop[i]);
}
}
} else {
//getEx(obj, prop)
var keys = (prop "").split(".");
ret = obj;
for (var i = 0; i & lt; keys.length; i ) {
ret = ret[keys [i]];
}
if (returnJson) {
var json = {};
json[prop] = ret;
return json;
}
}
return ret;
},
The "evil" if in the above case can be optimized as:
getEx: FunctionH.overload({
"*,array,*": function(obj, prop, returnJson) {
if (returnJson) {
ret = {};
for (var i = 0; i & lt; prop.length; i ) {
ret[prop[i]] = ObjectH.getEx (obj, prop[i]);
}
} else {
ret = [];
for (var i = 0; i & lt; prop.length; i ) {
ret[i] = ObjectH.getEx(obj, prop[i]);
}
}
return ret;
},
"*,string,*": function( obj, prop, returnJson) {
var keys = (prop "").split(".");
ret = obj;
for (var i = 0; i & lt; keys.length ; i ) {
ret = ret[keys[i]];
}
if (returnJson) {
var json = {};
json[prop] = ret;
return json;
}
return ret;
}
}),
OK, this form may seem better than the original to some people A little, but we can actually go further -
getEx: FunctionH.overload(function(args) {
return "prop is " ObjectH.getType(args[1]);
},{
"prop is array": function(obj, prop, returnJson) {
if (returnJson) {
ret = {};
for (var i = 0; i & lt; prop.length; i ) {
ret [prop[i]] = ObjectH.getEx(obj, prop[i]);
}
} else {
//getEx(obj, props)
ret = [];
for (var i = 0; i & lt; prop.length; i ) {
ret[i] = ObjectH.getEx(obj, prop[i]);
}
}
return ret;
},
"prop is string": function(obj, prop, returnJson) {
var keys = (prop "").split(".");
ret = obj;
for (var i = 0; i & lt; keys.length; i ) {
ret = ret[keys[i]];
}
if (returnJson) {
var json = {};
json[prop] = ret;
return json;
}
return ret;
}
}),
There is also the "annoying" third parameter, so we simply dealt with it too -
getEx: FunctionH.overload(function(args) {
return "prop is " ObjectH.getType(args[1]) " and returnJson is " args[2];
},{
"prop is array and returnJson is true": function(obj, prop, returnJson) {
ret = {};
for (var i = 0; i & lt; prop.length ; i ) {
ret[prop[i]] = ObjectH.getEx(obj, prop[i]);
}
return ret;
},
"prop is array and returnJson is false": function(obj, prop, returnJson) {
ret = [];
for (var i = 0; i & lt; prop.length; i ) {
ret[i] = ObjectH.getEx(obj, prop[i]);
}
return ret;
},
"prop is string and returnJson is true": function(obj, prop, returnJson) {
var keys = (prop "").split(".");
ret = obj;
for (var i = 0; i & lt; keys.length; i ) {
ret = ret[keys[i]];
}
var json = {};
json[prop] = ret;
return json;
},
"prop is string and returnJson is false": function(obj, prop, returnJson) {
var keys = (prop "").split(".");
ret = obj;
for (var i = 0; i & lt; keys.length; i ) {
ret = ret[keys[i]];
}
return ret;
}
}),
For example, browser sniffing and feature detection can also use this mode (of course, this form has advantages and disadvantages, users can weigh it themselves) -
foo = FunctionH.overload(function() {
return MSIE ? "IE": "NotIE";
},{
"IE": function() {...}
"NotIE": function() {...}
});