javascript,关于闭包函数调用

时间:2017-05-22 09:26:40

标签: javascript closures

我对javascript很新,我遇到了关于函数调用和闭包的问题。

以下是我在w3schools尝试过的代码,



<!DOCTYPE html>
    <html>
    <body>

    <p>Counting with a local variable.</p>

    <button type="button" id="btn">Count!</button>

    <p id="demo">0</p>

    <script>
    var add = (function (test) {
       var counter = 0;
       return function (test) {return counter += test;}
    })();

    /*function add(test){
       var counter = 0;
       return function (test) {return counter += test;}
    }*/

    function myFunction(){
	   document.getElementById("demo").innerHTML = add(123);
       //document.getElementById("demo").innerHTML = add().call(this, 123);
    }

    var btn = document.getElementById("btn");
    btn.addEventListener("click", myFunction);
    </script>

    </body>
    </html>
&#13;
&#13;
&#13;

它适用于当前代码,每按一次按钮,段落中的数字(id =&#34; demo&#34;)增加123.

但是当我尝试使用注释代码创建一个带有完全相同代码的闭包的函数时,段落值在每次onclick时都保持为123。

在这种情况下,我有几个问题要问。

1.代码:

  

var add =(function(test){...})();

最后一个括号的用法是什么?如果我们为最后一个括号提供参数,我们怎样才能在变量的匿名函数声明中使用它(var add)?

2.为什么这两种定义函数的方法导致不同的结果?

非常感谢,感谢任何帮助。

修改

&#13;
&#13;
<!DOCTYPE html>
<html>
<body>

<p>Counting with a local variable.</p>

<button type="button" id="btn">Count!</button>

<p id="demo">0</p>

<script>
/*var add = (function (test) {
    var counter = 0;
    return function (test) {return counter += test;}
})();*/

function add(test){
    var counter = 0;
    return function (test) {return counter += test;}
}

function myFunction(){
	//document.getElementById("demo").innerHTML = add(123);
    document.getElementById("demo").innerHTML = add().call(this, 123);
}

var btn = document.getElementById("btn");
btn.addEventListener("click", myFunction);
</script>

</body>
</html>
&#13;
&#13;
&#13;

当我使用注释代码来声明函数时,似乎代码运行没有错误,但只是一个错误,段落的整数没有增加。

3 个答案:

答案 0 :(得分:1)

你一直得到123的原因是因为每次你点击按钮时,你会得到一个新的内部函数,带有一个值为0的计数器变量的闭包;因此counter的值始终为0,当您将123添加到0时,您将获得123。 如果将闭包部分移出事件处理程序,则会得到与第一种情况完全相同的结果。

注意第var inner = add(); //<---Notice this line行。这将关闭一次,随后您将继续增加counter的值。

另外,请注意myFunction内的这一行:

document.getElementById("demo").innerHTML = inner.call(this, 123);

这里我们调用前面引用的内部函数。

/*var add = (function (test) {
      var counter = 0;
      return function (test) {return counter += test;}
  })();*/

function add(test) {
  var counter = 0;
  return function(test) {
    return counter += test;
  }
}

var inner = add(); //<---Notice this line
function myFunction() {
  //document.getElementById("demo").innerHTML = add(123);
  document.getElementById("demo").innerHTML = inner.call(this, 123);
}

var btn = document.getElementById("btn");
btn.addEventListener("click", myFunction);
<p>Counting with a local variable.</p>

<button type="button" id="btn">Count!</button>

<p id="demo">0</p>

答案 1 :(得分:0)

  1. ()用于调用刚刚声明的匿名函数,并返回另一个匿名函数。如果您提供参数,它将被输入您的功能(测试)。在这种情况下,您实际上不需要第一个测试参数。它只是没用过。
  2. 对于您的注释代码,它会返回一个函数。并且永远不会调用该函数。

答案 2 :(得分:0)

()最后一个括号是执行它。

你所展示的例子是IIFE的例子。 IIFE用于限制所有ur变量的范围,以便可以对命名空间进行demarkcated。

//without params
(function(){
       //...
})()

//-OR- (both are same)

(function(){
       //...
}())

//with params. if u ever wondered how that $ variable was being used in jquery, this is how.
(function(jquery){
})(jquery);

//es6
(
() => { ... }
)()

闭包是一种编程概念,其中(否则)允许scoped-out变量持久化。不要使用带有大对象集合的闭包!!!“

var outer = function(p1){
    var inner = function (p2) {
        return (p1 + p2);
    return inner;
}; //outer ends.    

var x = outer(10);
x(20); //20 + 10;
x(30); //30 + 10;
x(40); //40 + 10;
相关问题