首页 >社区问答列表 >javascript - 解释一下这段代码的含义

javascript - 解释一下这段代码的含义

var ninja = {};

addMethod(ninja,'whatever',function(a){console.log(arguments.length);});
addMethod(ninja,'whatever',function(a,b){console.log(arguments.length);});
addMethod(ninja,'whatever',function(){console.log(arguments.length);});

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);
  };
}

ninja.whatever();

这是一段出自《Secrets of the JavaScript Ninja》的代码,作者说它的作用是实现函数的重载,但是对于整个的运行过程我还是理解不透,麻烦懂的人解释一下。

  • 巴扎黑
  • 巴扎黑    2017-04-10 15:22:523楼

    我猜你主要是没看懂apply方法

    调用函数,并用指定对象替换函数的 this 值,同时用指定数组替换函数的参数。

    https://msdn.microsoft.com/zh-cn/library/4zc42wh1(v=vs.94).aspx

    +0添加回复

  • 回复
  • 黄舟
  • 黄舟    2017-04-10 15:22:522楼

    这段代码的作用就是实现函数的重载,首先你要了解一下什么是“函数的重载”,然后addMethod这个函数的第三个参数是一个函数,但是参数的数量是不确定的,所以关键就在这~~~~~,在C++中,

    int   Fun_Sum(int   A,int   B) 
    { 
            return   (A+B); 
    } 
    float   Fun_Sum(float   A,float   B) 
    { 
            return   (A+B); 
    } 
    double   Fun_Sum(double   A,double   B) 
    { 
            return   (A+B); 
    } 
    

    在JS中就是参数的数量不同,就搞一个重载。
    JS中没有重载,但是可以使用arguments间接的实现重载。
    还有就是这里有一个apply的知识点,这个google一下,或者楼上给出的网址就有对apply非常细致的讲解。
    我的理解是这个样子,有什么错误,欢迎大神指出,共同进步

    +0添加回复

  • 回复
  • 迷茫
  • 迷茫    2017-04-10 15:22:521楼

    楼上的回答的很厉害了;但为什么whatever(1)会被执行2次?

    1)整个实现利用了闭包的特性,能够访问其嵌套函数的变量-old。
    每次addmethod函数的执行都能导致闭包的作用域链通过old变量被不断的延长
    在调用具体方法时,也通过old变量在作用域链一层一层查询匹配的实际方法实现(通过比较参数长度,fn·length函数形参长度,arguments.length实参长度)并调用它

    2)type old=='function' 处理如果没有方法匹配的情况

    +0添加回复

  • 回复