JS
//【示例1】JavaScript不支持函数重载,不能定义同样的函数然后通过编译器去根据不同的参数执行不同的函数。但是JavaScript可以通过自身属性去模拟函数重载。
function calculate() {
if (arguments.length == 2) {
return arguments[0] + arguments[1];
}
if (arguments.length == 3) {
return arguments[0] * arguments[1] * arguments[2];
}
}
alert(calculate(1, 3))
//【示例2】上面示例看起来不错,但随着需求的增多,if分支就会越来越庞大,而且对应的模式也越来越难看。因此,可以考虑使用另一个策略来实现这个需求。
var map = function (arr, callback, pThis) {
var len = arr.length;
var rlt = new Array(len);
for (var i = 0; i < len; i++) {
if (i in arr) rlt[i] = callback.call(pThis, arr[i], i, arr);
}
return rlt;
}
/** @method overload
* @static
* @optional {dispatcher} 用来匹配参数负责派发的函数
* @param {func_maps} 根据匹配接受调用的函数列表
* @return {function} 已重载化的函数
*/
var FunctionH = {
overload: function (dispatcher, func_maps) {
if (!(dispatcher instanceof Function)) {
func_maps = dispatcher;
dispatcher = function (args) {
var ret = [];
return map(args, function (o) { return typeof 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);
}
}
}
}
};
var Calculate = FunctionH.overload({
'number,number': function () {
return arguments[0] + arguments[1];
},
'number,number,number': function () {
return arguments[0] * arguments[1] * arguments[2];
}
});
alert(Calculate(1,2,3));
//【示例3】利用上面示例的方法和设计思路,可以设计浏览器兼容的重载函数。
var MSIE = navigator.userAgent.indexOf('MSIE') !== -1;
var foo = FunctionH.overload(function () {
return MSIE ? "IE" : "NotIE";
}, {
"IE": function () {
alert('this is ie');
},
"NotIE": function () {
alert('notie');
}
});
foo();
//【示例4】而覆盖(Overrid)则是子类中定义的方法与超类中方法同名,且参数类型和个数也相同,当子类被实例化之后,从超类中继承的同名方法将被隐藏。
function A(){ // 超类A
this.m = function(){ // 超类的本地方法m()
alert("A");
}
}
function B(){ // 子类B
this.m = function(){ // 子类的本地方法m()
alert("B");
};
}
B.prototype = new A(); // 通过原型继承方法,类B继承类A
B.prototype.constructor = B; // 恢复B类的原型对象的构造器
var b = new B(); // 实例化B
b.m(); // 返回字符B,说明子类B的方法m()将覆盖A的方法m()
function A(){ // 超类A
this.m = function(){ // 超类的本地方法m()
alert("A");
}
}
function B(){ // 子类B
var m = this.m; // 先使用私有变量保存超类继承来的同名方法
this.m = function(){ // 子类的本地方法m()
m.call(this); // 在当前对象中调用子类私有变量中存储的超类方法m()
alert("B");
};
}
B.prototype = new A(); // 通过原型继承方法,类B继承类A
B.prototype.constructor = B; // 恢复B类的原型对象的构造器
var b = new B(); // 实例化B
b.m(); // 返回字符B,说明子类B的方法m()将覆盖A的方法m()