【问题标题】:javascript, about closure function calljavascript,关于闭包函数调用
【发布时间】:2017-05-22 09:26:39
【问题描述】:

我对 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>

对于当前的代码来说效果很好,每次我按下按钮时,段落中的数字(id="demo") 都会增加 123。

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

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

1.代码:

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

最后一个括号有什么用?如果我们在最后一个括号中提供参数,我们如何在变量(var add)的匿名函数的声明中使用它?

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

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

编辑


<!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>

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

【问题讨论】:

标签: javascript closures


【解决方案1】:

您一直得到 123 的原因是,每次单击按钮时,您都会使用一个新的内部函数,该函数对值为 0 的计数器变量进行闭包;所以counter 的值始终保持为 0,当你将 123 加到 0 时,你得到 123。 如果将闭包部分移出事件处理程序,您将获得与第一种情况完全相同的结果。

注意var inner = add(); //&lt;---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>

【讨论】:

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

    【讨论】:

    • 请问在这种情况下,我可以通过什么方式调用该函数?
    【解决方案3】:

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

    您展示的示例是 IIFE。 IIFE 用于限制所有 ur 变量的范围,以便可以划分命名空间。

    //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
    (
    () => { ... }
    )()
    

    闭包是一个编程概念,其中(否则)范围外的变量被允许持续存在。不要对大对象集合使用闭包!!!

    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;
    

    【讨论】:

      猜你喜欢
      • 2022-07-06
      • 1970-01-01
      • 2015-05-22
      • 2017-05-20
      • 2015-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-05
      相关资源
      最近更新 更多