Javascript函数重载,请解释John Resig(Jquery方式)文章

时间:2015-01-27 09:51:59

标签: javascript

我理解基于arguments对象实现JavaScript重载,或者通过显式检查参数的类型和长度来理解。请解释这篇文章:http://ejohn.org/blog/javascript-method-overloading/

1 个答案:

答案 0 :(得分:2)

下面的函数中有两个概念,我认为可能是您混淆的原因。

以下代码创建的日志记录可以帮助您了解正在发生的事情。

// addMethod - By John Resig (MIT Licensed)
function addMethod(object, name, fn) {
  var old = object[name];
  object[name] = function() {
    if (fn.length == arguments.length) {
      console.log('Arguments and parameters count are the same, found the function');
      return fn.apply(this, arguments);
    }
    if (typeof old == 'function') {
      console.log('Arguments and parameters count are not the same, try the next function in the closure stack');
      return old.apply(this, arguments);
    }
  };
}

function Users() {
  // This will be at the bottom of the stack, every call will have to go through the functions below
  addMethod(this, "find", function() {
    console.log('Called with 0 arguments');
  });
  // This will be at the middle of the task
  addMethod(this, "find", function(name) {
    console.log('Called with one argument');
  });
  // This is the one with the least overhead
  addMethod(this, "find", function(first, last) {
    console.log('Called with two arguments');
  });
}

var users = new Users();
users.find();
users.find('John');
users.find('John', 'Resig');

请记住在尝试理解它们时逐步执行功能。右键单击下面的图像,然后选择“在新选项卡中打开图像”

Closure stack

这里的addMethods会减少开销和恕我直言,更好的语法和更少的重复。

// addMethods - By Juan Methods, inspired by John Resig (MIT Licensed)
function addMethods(object, name /* fn, fn, fn ... */ ) {
  // Key is the parameter count for each passed in function, value is the function itself */
  var functionMap = {};
  for (var i = 2; i < arguments.length; i++) {
    functionMap[arguments[i].length] = arguments[i];
  }

  object[name] = function() {
    functionMap[arguments.length].apply(this, arguments);
  };
}

function Users() {
  // Now every function has constant overhead of a single map lookup, which
  // is less expensive than multiple method calls up the closure stack
  addMethods(this, "find", 
    function() {
      console.log('Called with 0 arguments');
    }, 
    function(name) {
      console.log('Called with one argument');
    },
    function(first, last) {
      console.log('Called with two arguments');
    }
  );
}

var users = new Users();
users.find();
users.find('Jack');
users.find('John', 'Resig');