为什么javascript apply函数可以递归工作?

时间:2018-08-17 05:04:40

标签: javascript overloading apply

我正在学习John Resig的javascript函数重载。

https://johnresig.com/blog/javascript-method-overloading/

在练习此链接上的示例时,我有一个问题:

function addMethod (object, name, fn) {
  var old = object[ name ]
  object[ name ] = function () {
    console.log(fn.length)
    console.log(arguments.length)
    if (fn.length === arguments.length) {
      let ret = fn.apply(this, arguments)
      console.log(ret)
      return ret
    } else if (typeof old === 'function') {
      let ret = old.apply(this, arguments)
      console.log(ret)
      return ret
    }
  }
}

addMethod用于函数重载,实际函数内部的行为是在我调用该函数时发生的。

执行apply函数时出现问题。 如果函数参数不同,则调用old.apply函数。 如果调用此函数,它将以递归方式工作。

例如,如果没有实际的function参数,则第一个argument.length为2,并且调用old.apply。同样,在递归调用的函数中,arguments.length的值为1。为什么递归调用apply函数?

ps。 AddMethod

function Users() {}
addMethod(Users.prototype, 'find', function () {
  console.log('ARG 0')
  // Find all users...
})

addMethod(Users.prototype, 'find', function (name, age) {
  console.log('ARG 1')
  // Find a user by name
})

调用功能:

var users = new Users()
users.find() // Finds all
users.find('John') // Finds users by name

1 个答案:

答案 0 :(得分:1)

执行时

addMethod(Users.prototype, 'find', function () {...}

然后将Users.prototype.find设置为包含该语句中的函数(fn)的包装函数。

然后执行

addMethod(Users.prototype, 'find', function (name, age) {...}

将先前的包装器函数转换为旧变量,并将新的包装器函数绑定到Users.prototype.find

调用users.find()(不带任何参数)时,似乎好像调用了find函数(包含console.log语句),但实际上,您调用了绑定到{{1}的最后一个包装函数}。将打印变量。 由于参数不匹配,因此包装器函数将调用旧的“包装器”函数(在Users.prototype.find变量中提示)。变量将再次打印。然后调用由old定义的实际“查找”功能。

这并不是真正的递归,您只存储了两个函数,第一个(包装器)函数调用了第二个。然后结束。