在一步中定义和调用函数

67
在Javascript中,是否有一种定义函数并立即调用它的方式,以便可以重复使用它?我知道你可以使用一次性匿名函数:
(function(i) {
    var product = i * i;
    console.log(product);
    // Can't recurse here because there's no (ECMA standard) way for the 
    // function to refer to itself
}(2)); // logs 4

或者您可以给函数命名,然后在之后调用它:

function powers(i) {
    var product = i * i;
    console.log(i * i);
    if (product < 1e6) { powers(product) };
}

powers(2); // Logs 4, 16, 256...

但是有没有更简洁的方式在定义和调用函数时一起完成呢?就像两个示例的混合体一样?

不能这样做并不会妨碍我做任何事情,但感觉这将是一种很好的表达方式,用于编写递归函数或需要在$(document).ready()时运行但稍后需要根据情况改变等函数。


可能是 Can I name a javascript function and execute it immediately? 的重复问题。 - brichins
4个回答

60
您可以尝试:

(window.powers = function(i) {
  /*Code here*/
  alert('test : ' + i);
})(2);
<a href="#" onclick="powers(654)">Click</a>

工作链接:http://jsfiddle.net/SqBp8/

它在加载时被调用,并且我已经将其添加到一个锚标签中以更改参数和alert


4
聪明的解决方案!即使没有使用 window.,它也能正常工作,但是暗示的全局变量是有害的... - quis
1
只需在即时执行函数之前添加 var powers;,你就可以开始了。 - Yohaï-Eliel Berreby

41

如果你只想在函数内部访问该函数,可以在function关键字后指定一个名称:

> (function fac (n) {
    return (n === 0 ? 1 : n*fac(n-1));
  })(10)
3628800

这是一个标准功能(参见ECMA-262,第5.1版,第98页)。


7
它所执行的任务非常优雅。 - quis

15

这里所有的答案都接近你所需要的,但它们存在一些问题(如将其添加到全局作用域中,实际上没有调用它等)。下面结合了本页面的几个示例(尽管不幸的是,它需要你记住 arguments.callee):

var test = (function() {
  alert('hi');
  return arguments.callee;
})();

稍后,您可以称其为:

test();

2
唯一的问题是arguments.callee在ES5严格模式下已被弃用,并会抛出错误。 - Tivie
5
@Tivie 但是你可以给这个匿名函数命名。 var test = (function fn() { alert('hi'); return fn; })(); - Evan Kennedy

6
如果您不关心返回值,您可以这样做。
var powers = function powers(i) {
    var product = i * i;
    console.log(i * i);
    if (product < 1e6) { powers(product) };
    return powers;
}(2);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接