2017-01-10 32 views
0

这里是一段代码,点击该按钮时,一个让数增量:自调用函数闭inJavaScript

<script type="text/javascript"> 
    var incrementClickCount = (function() { 
     var clickCount = 0; 
     return function() { 
      return ++clickCount; 
     } 
    })(); 
</script> 
<input type="button" value="click me" onclick="alert(incrementClickCount());" /> 

我不知道那是什么,我认为我们应该得到的值“1”每次当我们点击按钮,这样的序列将是

步骤1:通过自自我调用的外部函数调用,内匿名函数的定义存储在增量incrementClickCount变量。

第2步:当单击该按钮,调用内部匿名函数从0更改的clickCount值设置为1,这样我们就得到1作为输入,很公平。

第3步:这里是我不明白的棘手的部分,当我们再次单击按钮时。我们实际上调用了一个新的内部匿名函数,所以输入应该是1,为什么它现在是2?就这样正常的Java或C#功能:

public int getNumber() 
{ 
    int clickCount = 0; 
    return addNumber(clickCount); 
} 

public int addNumber(int number) 

{ 
    return number++; 
} 

不管有多少次我打电话getNumber()功能,我总是得到1而不是1,2,3,4,5 ....

+0

每次函数被调用你的clickCount值重置为0,这就是为什么它总是显示1. – mnemosdev

回答

3
当我们再次点击按钮时,我们会看到

。我们实际上调用一个新的内部匿名函数

当IIFE解析从IIFE返回的匿名函数号。这就是为什么他们被称为立即调用函数表达式。线})();上的()调用它(不是调用返回函数的incrementClickCount())。

时间单击该按钮(包括第一次),你调用当时返回(以及分配给incrementClickCount)的相同功能。

IIFE永远不会再被调用,所以行var clickCount = 0;永远不会再被执行。

+0

但是由于IIFE第一次被调用,所以可变的clickCount应该被破坏,不是吗?就像函数中的变量一样,一旦函数被调用,函数中的变量就不能再被访问了吗? – slowjamsz11

+0

“变量clickCount应该被销毁 - 编号IIFE(匿名函数)的返回值被分配给该变量,除了调用该函数外,没有任何东西与该变量有任何关系,没有任何东西可以销毁它。 – Quentin

-1

您应该在函数外部创建变量clickCount,然后启用onClick函数来修改其值。干杯。

+0

'clickCount' is defined (匿名,返回)函数之外,这就是代码工作的原因 – Quentin

+0

感谢分享 – mnemosdev

1

起初incrementClickCount函数调用IIFE返回内部函数,它操作clickCount变量并递增它。
所有进一步的电话将是ON,内部功能。所以clickCount变量只能分配var clickCount = 0;一次。
考虑以下的输出:

console.log(incrementClickCount); 
// outputs the inner function definition  
return function() { 
    return ++clickCount; 
} 

console.log(incrementClickCount()); // 1 
console.log(incrementClickCount()); // 2 
console.log(incrementClickCount()); // 3 

这里是一个很好的例子:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#Emulating_private_methods_with_closures

+0

但是由于IIFE已经第一次被调用,所以变量clickCount应该被销毁,不是吗?就像变量一样一个函数,一旦函数被调用,函数中的变量就无法再被访问了? – slowjamsz11

+0

@ slowjamsz11,不,每个闭包都有它自己的环境......共享环境是在一个匿名函数,一旦它被定义就会被执行。*在你的情况下'clickCount'变量是“*共享环境*”的一部分 – RomanPerekhrest

1

,当你点击你所呼叫的按钮,每一次 “incrementClickCount()” 函数。

但是当代码实际运行第一次时,变量'incrementClickCount'从自调用函数获取返回函数的值。

所以简单变量'incrementClickCount'包含内部函数,如下所示。

incrementClickCount = function() { 
      return ++clickCount; 
     } 

并且clickCount值由于关闭而可用于此方法。所以它每次增加它,而不是重新设置值。

自我调用函数是没有得到所谓的每一次,原因在于“的clickCount”没有得到重置为0

+0

但是由于IIFE首次被调用,所以应该销毁变量clickCount,不是吗?就像函数中的变量一样,一旦函数被调用,函数中的变量就不能再被访问了吗? – slowjamsz11

+0

@ slowjamsz11 nope,因为那部分代码只执行一次,之后它在内存中,因为变量在全局范围内声明,不在函数范围内。 – MGA