在JavaScript中,如果用括号调用函数会有所不同吗?


105

在调用带有空括号或完全不带括号的函数时,我注意到了一个区别。但是,我没有将任何参数传递给该函数,所以我想知道两者之间的区别是什么:

window.onload = initAll();

window.onload = initAll;

请解释其背后的原理。


24
@JS Bangs-仅使用美国英语;没有其他地方。尽管程序员倾向于称它们为“括号”以避免混淆,但是在英国英语中,四舍五入的圆括号被简单地称为方括号。方括号称为“方括号”。en.wikipedia.org/wiki/Bracket
Rob Levine

13
值得一提的是,UNICODE的正式名称是括号。0028 ( 左括号=开括号(1.0)和0029 ) 右括号=右括号(1.0) - unicode.org/charts/charindex.html#P 什么Dictionary.com不得不说的吧- dictionary.reference.com/浏览/括号中的 “垂直弯曲的线中的一个或两个,()...”

8
因此,这不仅是“美国英语”,而且是国际标准的定义,因为UNICODE是国际标准。

2
@fuzzy-认真地从哪里获得事实?{}被称为松鼠括号。
阿努拉格

7
@fuzzy棒棒糖-Unicode是将字符编码为字节而不是命名的国际标准。unicode文档的作者并未声称给定的字符名称是国际标准。这是他们定义的代码与字符。但是,您可能需要注意,它们也将[和]称为方括号-(而不仅仅是“括号”),并且它们还将所有[,{和(称为方括号字符)。您应努力理解细微差别以不同的地方使用相同的词的方式,如果您是国际团队的一员,这点非常重要
Rob Levine 2010年

Answers:


161
window.onload = initAll();

执行 initAll() 直线距离和分配函数的返回值window.onload。这通常不是您想要的。initAll()为此必须返回一个函数。

window.onload = initAll;

这将实际函数分配给window.onload-这是可能的,因为在JavaScript中,如@Felix所说,函数是第一类对象-无需执行它。initAll将由load事件执行。


18
这里要提到的重要一点是,函数是JavaScript中的一流对象。
菲利克斯·克林

136

Pekka所说的是正确的,但是我想用一个例子详细说明一下,这将有助于向不完全理解函数指针或委托的人进行解释。

我不会使用,window.onload因为这有点想演示。我将使用一个简单的乘法函数进行演示:

function Multiply(operator, operand) {
    return operator * operand;
}

同样可以这样写:

Multiply = function(operator, operand) {
    return operator * operand;
}

虽然在第一个示例中,含义可能并不明显,但是第二个示例更清楚地表明,我们正在将具有2个参数的函数分配给名为的变量Multiply,并且这种函数作为赋值的概念在整个JavaScript中很常见。这只是一个事实,说明函数是“一流公民”,也就是说,可以像传递值一样准确地传递它们。

所以现在到分配的区别:

var operator = 3;
var operand = 4;
var ret = Multiply(operator, operand);

在定义ret变量时,Multiply将执行并分配返回值- ret等于12。

让我们以另一种方式再次尝试:

var operator = 3;
var operand = 4;
var ret = Multiply;

现在,在定义时retret成为您的Multiply功能,而不是从您的Multiply功能获得的结果。调用ret()将导致您的Multiply函数被执行,您可以完全像调用该函数一样调用它Multiply(operator, operand)

var out = ret(3, 4);

是相同的

var out = Multiply(3, 4);

您实际上已经说过,您将ret用作的代表Multiply()。在调用时ret,我们实际上是在指该Multiply函数。

回到您的window.onload。认为是:

window.onload = function() {
    //Doing what all good window.onload functions should do...
}

initAll = function() {
    return 12;
}

正如您所看到的,window.onload该函数与其他任何函数一样,没有什么特别的。您可以给它分配一个值,给它分配一个函数,如果需要,可以将其为空-关键是没有什么window.onload比您自己的函数更特别了。唯一略有不同的是,它在加载时由窗口调用。[免责声明:我从未真正取消过窗口函数,因此我不确定这是否会带来负面影响。希望他们在调用函数之前检查是否已分配了一个函数,即if (window.onload) window.onload();]。

现在initAll(),我们要说的是:

window.onload = initAll();

最好这样说:

window.onload = 12;

但是,当我们说不initAll带括号时,我们真正要说的是:我想用新函数替换我的window.onload函数,即我想用我的initAll函数替换它,以便任何调用都能window.onload运行initAll码。

所以:

window.onload = function() {
    //Doing what all good window.onload functions should do...
}

替换为:

window.onload = function() {
    return 12;
}

因此,任何对的调用都window.onload将执行您的initAll函数,而不是window.onload原来执行的函数。您已用新功能替换了原始功能。

实际上,您可以同样地写:

window.onload = function() {
    //Write all your init code right in here instead of having a separate 
    //initAll function.
}

另一个可能更好地演示的示例是:

var d = new Date();
var currentTime = d.getTime();

当时d定义的时间是分配给currentTime。很好,但这仅在我们要找出包含该代码的函数什么时候被调用时(即在页面加载时)才有用。如果我们希望在任何时候currentTime调用当前时间怎么办?

var currentTime = function() {
    var d = new Date();
    return d.getTime();
}

var a = currentTime(); //The current time at the point a is defined...
var b = currentTime;   //b is a functional reference to currentTime...
var c = b(); //The current time when variable c is defined
var d = c; //The current time when variable c was defined

请注意,我们如何完全调用b()我们的cd作业currentTime()


很棒的答案!
Shadi Almosri

嘿,如果我想添加一个在事件监听器上接受参数的函数,该怎么办?
谢米尔斯

16

javascript中的函数是一等公民,因此可以分配给其他变量或作为参数传递。

所以,当你这样做

window.onload = initAll;

您正在设置对象的onload属性window以引用initAll函数本身。

当你做

window.onload = initAll();

您正在设置onload属性以保存initAll 的返回值,因为它将在该行上执行。


10

initAll 是对函数值的引用,并在函数名称后附加方括号运算符RUNS该函数对象。

所以如果你做类似的事情

a = initAll

然后a将与initAll-例如您可以做的a()- 相同

a = initAll()

该变量a将获取执行initAll函数的返回值


8

我迟到了6年,但我觉得比上面的答案要简单得多。

这是TLDR;或鸟瞰打电话时使用的功能和不使用()

让我们以以下功能为例:

function foo(){
return 123;
}

如果您登录“ foo”- ()

console.log(foo); 

---outout------
function foo(){
return 123;
}

不使用任何()方法来获取函数本身。如果希望将其作为回调传递,则可以执行此操作。


如果您登录为“foo()” - ()

console.log(foo());
-----output-----
 123

使用()后的功能的手段来执行功能,并返回它的值

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.