Javascript 理解函数重载有困难

Javascript 理解函数重载有困难,javascript,Javascript,我很难从《Javascript忍者的秘密》一书中理解这个例子 概念是您有一个addMethod函数,它允许您将同一方法的多个版本传递给一个对象,不同之处在于这些方法接受的参数数量,以及它们处理这些参数的方式 我不明白这背后的“机制”。在inspector中,我只看到了第一个方法,但不知何故,当我使用不同的参数运行find方法时,它仍然设法使用它的适当变体。但是怎么做呢?在使用三个版本运行addMethod后,这些方法如何仍然可用? 你能帮我理解吗 将方法绑定到对象的函数: addMethod =

我很难从《Javascript忍者的秘密》一书中理解这个例子

概念是您有一个addMethod函数,它允许您将同一方法的多个版本传递给一个对象,不同之处在于这些方法接受的参数数量,以及它们处理这些参数的方式

我不明白这背后的“机制”。在inspector中,我只看到了第一个方法,但不知何故,当我使用不同的参数运行
find
方法时,它仍然设法使用它的适当变体。但是怎么做呢?在使用三个版本运行
addMethod
后,这些方法如何仍然可用? 你能帮我理解吗

将方法绑定到对象的函数:

addMethod = function(object, name, fn) {
  var old;
  old = object[name];
  return object[name] = function() {
    if (fn.length === arguments.length) {
      return fn.apply(this, arguments);
    } else if (typeof old === 'function') {
      return old.apply(this, arguments);
    }
  };
};
然后,您可以指定与对象属性相同的函数名,如下所示:

addMethod(ninjas, 'find', function() {
  return this.values;
});

addMethod(ninjas, 'find', function(name) {
  var ninja, _i, _len, _ref, _results;
  _ref = this.values;
  _results = [];
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    ninja = _ref[_i];
    if (ninja.indexOf(name) !== -1) {
      _results.push(ninja);
    }
  }
  return _results;
});

addMethod(ninjas, 'find', function(first, last) {
  var ninja, _i, _len, _ref, _results;
  _ref = this.values;
  _results = [];
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    ninja = _ref[_i];
    if (ninja === ("" + first + " " + last)) {
      _results.push(ninja);
    }
  }
  return _results;
});
addMethod(忍者,'find',函数(){
返回这个值;
});
addMethod(忍者,'find',函数(名称){
var ninja,_i,_len,_ref,_results;
_ref=该值;
_结果=[];
对于(_i=0,_len=_ref.length;_i<_len;_i++){
忍者=_ref[_i];
如果(忍者索引(名称)!=-1){
_结果:推(忍者);
}
}
返回结果;
});
addMethod(忍者,'查找',函数(第一个,最后一个){
var ninja,_i,_len,_ref,_results;
_ref=该值;
_结果=[];
对于(_i=0,_len=_ref.length;_i<_len;_i++){
忍者=_ref[_i];
如果(忍者==(“”+第一名+“”+最后一名)){
_结果:推(忍者);
}
}
返回结果;
});

每次重载函数时,它都会使用旧函数并替换为检查要使用哪种重载的函数

添加第一个函数后,您的代码(大致)与:

ninjas.find = function(){
  if (arguments.length === 1) {
    // code for first overload
  }
}
ninjas.find = function(){
  if (arguments.length === 2) {
    // code for second overload
  } else {

    if (arguments.lenght === 1) {
      // code for first overload
    }

  }
}
添加第二个函数后,您的代码与:

ninjas.find = function(){
  if (arguments.length === 1) {
    // code for first overload
  }
}
ninjas.find = function(){
  if (arguments.length === 2) {
    // code for second overload
  } else {

    if (arguments.lenght === 1) {
      // code for first overload
    }

  }
}

每次您添加另一个重载时,都会在前面的代码周围添加另一个级别的检查。

每次您重载函数时,它都会将旧函数替换为检查要使用哪个重载的函数

addMethod = function(object, name, fn) {
  var old;
  old = object[name];
  return object[name] = function() {
    if (fn.length === arguments.length) {
      return fn.apply(this, arguments);
    } else if (typeof old === 'function') {
      return old.apply(this, arguments);
    }
  };
};
添加第一个函数后,您的代码(大致)与:

ninjas.find = function(){
  if (arguments.length === 1) {
    // code for first overload
  }
}
ninjas.find = function(){
  if (arguments.length === 2) {
    // code for second overload
  } else {

    if (arguments.lenght === 1) {
      // code for first overload
    }

  }
}
添加第二个函数后,您的代码与:

ninjas.find = function(){
  if (arguments.length === 1) {
    // code for first overload
  }
}
ninjas.find = function(){
  if (arguments.length === 2) {
    // code for second overload
  } else {

    if (arguments.lenght === 1) {
      // code for first overload
    }

  }
}
每次添加另一个重载时,都会围绕前面的代码添加另一个级别的检查

addMethod = function(object, name, fn) {
  var old;
  old = object[name];
  return object[name] = function() {
    if (fn.length === arguments.length) {
      return fn.apply(this, arguments);
    } else if (typeof old === 'function') {
      return old.apply(this, arguments);
    }
  };
};
让我们开始:

object[name]=function()
为对象分配一个函数

例如:

ninjas["find"] = function()
-----------------------------------------------------------------------
function                            -       fn.length == arguments.length
------------------------------------------------------------------------
ninjas.find()                       -        (0 == 0), uses `function ()`
ninjas.find("Rias")                 -        (1 == 1), uses `function (name)`
ninjas.find("Mohamed", "Rias")      -        (2 == 2), uses `function (first, last)`
ninjas.find("Mohamed", "Rias", "A") -        (? == 3), no match, returns `undefined`
然后使用第一个匹配项将命名的参数数(fn.length)与传入的参数数(arguments.length)进行比较。以便确定需要调用哪个函数

如果第一个条件不满足,那么它将检查旧函数的类型。如果它是一个函数,那么它只将参数应用于旧函数

fn.length
指传递的最外层函数

&

arguments.length
指最内部函数长度的参数

那么覆盖是如何工作的呢

正如您所看到的,每次调用
addMethod
时,它都会将函数引用到名为
old
的变量。然后根据
if
条件的结果,它将用较新的函数覆盖先前的函数

如果没有任何具有匹配变量的旧函数,它将返回未定义的

例如:

ninjas["find"] = function()
-----------------------------------------------------------------------
function                            -       fn.length == arguments.length
------------------------------------------------------------------------
ninjas.find()                       -        (0 == 0), uses `function ()`
ninjas.find("Rias")                 -        (1 == 1), uses `function (name)`
ninjas.find("Mohamed", "Rias")      -        (2 == 2), uses `function (first, last)`
ninjas.find("Mohamed", "Rias", "A") -        (? == 3), no match, returns `undefined`
让我们开始:

object[name]=function()
为对象分配一个函数

例如:

ninjas["find"] = function()
-----------------------------------------------------------------------
function                            -       fn.length == arguments.length
------------------------------------------------------------------------
ninjas.find()                       -        (0 == 0), uses `function ()`
ninjas.find("Rias")                 -        (1 == 1), uses `function (name)`
ninjas.find("Mohamed", "Rias")      -        (2 == 2), uses `function (first, last)`
ninjas.find("Mohamed", "Rias", "A") -        (? == 3), no match, returns `undefined`
然后使用第一个匹配项将命名的参数数(fn.length)与传入的参数数(arguments.length)进行比较。以便确定需要调用哪个函数

如果第一个条件不满足,那么它将检查旧函数的类型。如果它是一个函数,那么它只将参数应用于旧函数

fn.length
指传递的最外层函数

&

arguments.length
指最内部函数长度的参数

那么覆盖是如何工作的呢

正如您所看到的,每次调用
addMethod
时,它都会将函数引用到名为
old
的变量。然后根据
if
条件的结果,它将用较新的函数覆盖先前的函数

如果没有任何具有匹配变量的旧函数,它将返回未定义的

例如:

ninjas["find"] = function()
-----------------------------------------------------------------------
function                            -       fn.length == arguments.length
------------------------------------------------------------------------
ninjas.find()                       -        (0 == 0), uses `function ()`
ninjas.find("Rias")                 -        (1 == 1), uses `function (name)`
ninjas.find("Mohamed", "Rias")      -        (2 == 2), uses `function (first, last)`
ninjas.find("Mohamed", "Rias", "A") -        (? == 3), no match, returns `undefined`

尝试尝试一下
fn。应用
。尝试在函数中使用它并返回
fn.apply的结果。除此之外,试着一步一步地浏览代码,思考每一步会发生什么。试着用
fn.apply
进行一些实验。尝试在函数中使用它并返回
fn.apply的结果。除此之外,试着一步一步地浏览代码,思考每一步会发生什么。谢谢@Guffa,尽管我理解你的解释,但我很难理解当我调用
addMethod
时,如何不覆盖
find
方法。我认为这些方法直接存储在对象上,但事实并非如此。@LuisMartins:the
addMethod
获取属性的previos值并存储在局部变量中,然后替换属性。前面的方法引用仅存在于分配给
find
属性的新函数的闭包中。谢谢@Guffa,尽管我理解你的解释,但我很难理解调用
addMethod
时如何不覆盖
find
方法。我认为这些方法直接存储在对象上,但事实并非如此。@LuisMartins:the
addMethod
获取属性的previos值并存储在局部变量中,然后替换属性。前面的方法参考