Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/408.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用字符串数组创建嵌套函数的对象以形成对象键_Javascript_Coffeescript_Method Chaining - Fatal编程技术网

Javascript 使用字符串数组创建嵌套函数的对象以形成对象键

Javascript 使用字符串数组创建嵌套函数的对象以形成对象键,javascript,coffeescript,method-chaining,Javascript,Coffeescript,Method Chaining,我使用以下构造作为模拟对象,其功能类似于具有可链接方法的对象: PlayerNull = find : -> populate : -> exec : (callback) -> callback false, false 在我的测试中,我用真实模型替换这个模拟对象,我的控制器依次调用每个函数,例如: Model.find().populate().exec(callback) 由于我发现自己多次使用这个函数,我很好奇是否可以创建一个

我使用以下构造作为模拟对象,其功能类似于具有可链接方法的对象:

PlayerNull =
  find : ->
    populate : ->
      exec : (callback) ->
        callback false, false
在我的测试中,我用真实模型替换这个模拟对象,我的控制器依次调用每个函数,例如:

Model.find().populate().exec(callback)
由于我发现自己多次使用这个函数,我很好奇是否可以创建一个助手函数来简化它(稍微),使用以下形式的助手函数:

PlayerNull = helper.mockNest ['find', 'populate', 'exec'], (callback) ->
  callback false, false
我看到了以下函数代码,但这不起作用:

exports.mockNest = (func_names, func_final) ->
  func_names.reverse()
  func_next = func_final
  for func_name in func_names
    _func_next = func_next.bind({})
    _next = {}
    _next[func_name] = ->
      _func_next
    func_next = _func_next
  func_next

我意识到我需要克隆
func_next
每个循环,否则引用似乎会被维护,而分配给
func_next
似乎会改变以前的所有分配。

是的,您已经正确地确定了问题,即引用没有被维护,这是经典问题

然而,克隆函数在这里并没有真正的帮助,您的实际问题是

它在
\u func\u next
变量上创建一个闭包,该变量在每次循环迭代中都会修改

应该是这样

exports.mockNest = (func_names, func_final) ->
  func_names.reverse()
  func_next = func_final
  for func_name in func_names
    next = {}
    next[func_name] = func_next
    func_next = do (_next = next) ->
      () ->
        _next
  func_next

多亏了Bergi的解释,我得出了以下解决方案:

exports.mockNest = (func_names, func_final) ->

  # Assign the last function to the provided func_final
  func_name_final = func_names.pop()
  func_next = {}
  func_next[func_name_final] = func_final

  # Reverse the array so we build the object from last to first.
  func_names.reverse()
  for func_name in func_names
    ignore = do (func_name, _func_next = func_next) ->
      func_next = {}
      func_next[func_name] = ->
        _func_next
      return
  func_next
为了解释这些更改,我需要保留提供的func_final,因此我必须在循环之前赋值


此外,我还需要将
do
块分配给变量
ignore
,否则Coffeescript会将函数编译到不同的位置,其中对
func\u next
所做的更改是无序的。分配确保了
do
块的位置。

非常感谢您解释问题并让我注意到
do
关键字,非常酷,让我越过了终点线。你的最终代码没有完全工作,我将添加一个答案并接受它;但解决办法相当小。与您的代码相比,它甚至可以使用空的
func\u names
数组。
exports.mockNest = (func_names, func_final) ->

  # Assign the last function to the provided func_final
  func_name_final = func_names.pop()
  func_next = {}
  func_next[func_name_final] = func_final

  # Reverse the array so we build the object from last to first.
  func_names.reverse()
  for func_name in func_names
    ignore = do (func_name, _func_next = func_next) ->
      func_next = {}
      func_next[func_name] = ->
        _func_next
      return
  func_next