Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/456.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.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_Function_Recursion_Function Expression - Fatal编程技术网

递归调用javascript函数

递归调用javascript函数,javascript,function,recursion,function-expression,Javascript,Function,Recursion,Function Expression,我可以在变量中创建递归函数,如下所示: /* Count down to 0 recursively. */ var functionHolder = function (counter) { output(counter); if (counter > 0) { functionHolder(counter-1); } } 有了这个,函数保持器(3)将输出3210。假设我做了以下工作: var copyFunction = functionHo

我可以在变量中创建递归函数,如下所示:

/* Count down to 0 recursively.
 */
var functionHolder = function (counter) {
    output(counter);
    if (counter > 0) {
        functionHolder(counter-1);
    }
}
有了这个,
函数保持器(3)将输出
3
2
1
0
。假设我做了以下工作:

var copyFunction = functionHolder;
copyFunction(3)将如上所述输出
3
2
1
0
。如果我随后更改了
函数持有者
,如下所示:

functionHolder = function(whatever) {
    output("Stop counting!");
然后
函数保持器(3)将给出<代码>停止计数,如预期

copyFunction(3)现在给出
3
停止计数指的是
函数持有者
,而不是它本身所指的函数。在某些情况下,这可能是可取的,但是有没有一种方法来编写函数,以便它调用自己而不是保存它的变量

也就是说,是否可以仅更改
函数保持器(计数器-1)这样,当我们调用
复制函数(3)时,通过所有这些步骤仍然会得到
3
2
1
0
?我试过
这个(计数器-1)
但这给了我一个错误
这不是一个使用命名函数表达式的函数

: 您可以为函数表达式指定一个名称,该名称实际上是private,并且只能从函数ifself内部看到:

var factorial = function myself (n) {
    if (n <= 1) {
        return 1;
    }
    return n * myself(n-1);
}
typeof myself === 'undefined'
ECMAScript的第5版禁止在中使用参数。callee(),但是:

(From):在普通代码参数中。被调用方指的是封闭函数。这个用例很弱:只需命名封闭函数!此外,arguments.callee实质上阻碍了诸如内联函数之类的优化,因为如果访问arguments.callee,则必须能够提供对未内联函数的引用。arguments.callee是严格模式函数的不可删除属性,在设置或检索时抛出


您可以使用以下方式访问函数本身:

但是,这将在严格模式下中断。

下面是一个非常简单的示例: 请注意,
计数器
相对于
slug
的值“向后”计数。这是因为我们记录这些值的位置,因为函数在记录之前递归——因此,在记录发生之前,我们基本上一直在调用堆栈中嵌套得越来越深

一旦递归满足最后一个调用堆栈项,它就会“跳出”函数调用,而
计数器的第一个增量发生在最后一个嵌套调用的内部


我知道这不是发问者代码的“修复”,但考虑到标题,我想我会举一个递归的例子,以便更好地理解递归。我知道这是一个老问题,但我想如果你想避免使用命名函数表达式,我会再提出一个解决方案。(不是说你应该或不应该回避它们,只是提出另一种解决方案)


您可以使用Y-combinator:()

您可以这样使用它:

// ES5
var fn = Y(function(fn) {
  return function(counter) {
    console.log(counter);
    if (counter > 0) {
      fn(counter - 1);
    }
  }
});

// ES6
const fn = Y(fn => counter => {
  console.log(counter);
  if (counter > 0) {
    fn(counter - 1);
  }
});

我相信这是不赞成的(在严格模式下是不允许的)@Felix:是的,“严格模式”会给出一个
类型错误
,但我还没有发现任何正式声明
参数的内容。被调用方
(或任何违反严格模式的行为)在“严格模式”之外是不赞成的。谢谢你的回答!这两种方法都很有帮助,并以两种不同的方式解决了问题。最后,我随机决定接受哪一个:P+1,尽管它在IE8中有一点缺陷,而且
imf
在封闭的变量环境中实际上是可见的,并且它引用了实际
imf
函数的副本。不过,您应该能够将外部引用设置为
null
。谢谢您的回答!这两种方法都很有帮助,并以两种不同的方式解决了问题。最后,我随机决定接受哪一个:只是为了让我理解。在每次返回时乘以函数的原因是什么<代码>返回n*1(n-1)?为什么函数是这样工作的?if循环4次后。根据一些引用参数。被调用方将无法在严格模式下工作。NB在函数内部,这是指函数执行的上下文,而不是函数本身。在您的例子中,这可能指向全局窗口对象。
if (counter>0) {
    arguments.callee(counter-1);
}
var counter = 0;

function getSlug(tokens) {
    var slug = '';

    if (!!tokens.length) {
        slug = tokens.shift();
        slug = slug.toLowerCase();
        slug += getSlug(tokens);

        counter += 1;
        console.log('THE SLUG ELEMENT IS: %s, counter is: %s', slug, counter);
    }

    return slug;
}

var mySlug = getSlug(['This', 'Is', 'My', 'Slug']);
console.log('THE SLUG IS: %s', mySlug);
  var fn = (function() {
    var innerFn = function(counter) {
      console.log(counter);

      if(counter > 0) {
        innerFn(counter-1);
      }
    };

    return innerFn;
  })();

  console.log("running fn");
  fn(3);

  var copyFn = fn;

  console.log("running copyFn");
  copyFn(3);

  fn = function() { console.log("done"); };

  console.log("fn after reassignment");
  fn(3);

  console.log("copyFn after reassignment of fn");
  copyFn(3);
// ES5 syntax
var Y = function Y(a) {
  return (function (a) {
    return a(a);
  })(function (b) {
    return a(function (a) {
      return b(b)(a);
    });
  });
};

// ES6 syntax
const Y = a=>(a=>a(a))(b=>a(a=>b(b)(a)));

// If the function accepts more than one parameter:
const Y = a=>(a=>a(a))(b=>a((...a)=>b(b)(...a)));
// ES5
var fn = Y(function(fn) {
  return function(counter) {
    console.log(counter);
    if (counter > 0) {
      fn(counter - 1);
    }
  }
});

// ES6
const fn = Y(fn => counter => {
  console.log(counter);
  if (counter > 0) {
    fn(counter - 1);
  }
});