多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] # 定义 所谓**函数重载**,就是函数名称一样,但是输入输出不一样。或者说,允许某个函数有各种不同输入,根据不同的输入,调用不同的函数,然后返回不同的结果。 <br> **addMethod**函数如下: ~~~ // addMethod - By John Resig (MIT Licensed) function addMethod(object, name, fn){ var old = object[ name ]; object[ name ] = function(){ if ( fn.length == arguments.length ) return fn.apply( this, arguments ); else if ( typeof old == 'function' ) return old.apply( this, arguments ); }; } ~~~ 所谓**addMethod**函数,简单的理解,就是给某个**object**,添加一个指定**name**的函数**fn**。它利用了**闭包**,可以通过**old**变量将先后绑定的函数链接起来。 <br> <br> # 使用 你可以这样使用**addMethod**函数,将**find**函数直接添加到每个对象实例: ~~~ function Users(){ addMethod(this, "find", function(){ // Find all users... }); addMethod(this, "find", function(name){ // Find a user by name }); addMethod(this, "find", function(first, last){ // Find a user by first and last name }); } ~~~ <br> 你也可以将 **find** 函数添加到对象的 **prototype** ,这样所有对象实例将共享**find**函数: ~~~text function Users(){ addMethod(Users.prototype, "find", function(){ // Find all users... }); addMethod(Users.prototype, "find", function(name){ // Find a user by name }); addMethod(Users.prototype, "find", function(first, last){ // Find a user by first and last name }); } ~~~ **users**对象的 **find** 方法成功实现了重载,可以根据不同的输入调用不同的函数: ~~~text var users = new Users(); users.find(); // Finds all users.find("John"); // Finds users by name users.find("John", "Resig"); // Finds users by first and last name users.find("John", "E", "Resig"); // Does nothing ~~~ <br> <br> # 缺陷 这种方法有一些明显的缺陷: * 重载只能处理输入参数个数不同的情况,它不能区分参数的类型、名称等其他要素。(ECMAScript 4计划支持这一特性,称作Multimethods,然而该版本已被放弃)。 * 重载过的函数将会有一些额外的负载,对于性能要求比较高的应用,使用这个方法要慎重考虑。 <br> <br> # 优化 如果你担心只绑定单个函数时的性能问题,你可以使用如下**addMethod**函数: ~~~text // addMethod - By John Resig (MIT Licensed) function addMethod(object, name, fn){ var old = object[ name ]; if ( old ) object[ name ] = function(){ if ( fn.length == arguments.length ) return fn.apply( this, arguments ); else if ( typeof old == 'function' ) return old.apply( this, arguments ); }; else object[ name ] = fn; } ~~~ 这样绑定第一个函数时,将不会有额外的操作,既简单又快速。当绑定更多函数时,则与原**addMethod**函数一样,会有额外的性能损失。 这样做还有一个额外的好处:对于那些参数个数不符合要求的函数调用,将统一又第一个绑定的函数处理。这时调用**find**方法的输出如下: ~~~text var users = new Users(); users.find(); // Finds all users.find("John"); // Finds users by name users.find("John", "Resig"); // Finds users by first and last name users.find("John", "E", "Resig"); // Finds all ~~~ <br> <br> # 参考资料 [JavaScript函数重载](https://zhuanlan.zhihu.com/p/28072022)