Javascript 闭包解释

发布于 2024-09-06 02:38:03 字数 3037 浏览 5 评论 0原文

问题: 闭包似乎有很多好处,但有哪些缺点呢?另外,我对闭包的理解是否正确?最后,一旦创建了闭包,它们可以被销毁吗?

我读了一些关于 Javascript 闭包的文章。我希望有更懂行的人能够指导我的主张,纠正我的错误之处。

闭包的好处

  1. 通过使用内部函数将变量封装到局部作用域。 该函数的匿名性微不足道。

我发现有用的是做一些关于本地/全局范围的基本测试:

<script type="text/javascript">

   var global_text  = "";
   var global_count = 0;
   var global_num1  = 10;
   var global_num2  = 20;
   var global_num3  = 30;

   function outerFunc() {

      var local_count = local_count || 0;

      alert("global_num1: " + global_num1);    // global_num1: undefined
      var global_num1  = global_num1 || 0;
      alert("global_num1: " + global_num1);    // global_num1: 0

      alert("global_num2: " + global_num2);    // global_num2: 20
      global_num2  = global_num2 || 0;         // (notice) no definition with 'var'
      alert("global_num2: " + global_num2);    // global_num2: 20
      global_num2  = 0;

      alert("local_count: " + local_count);    // local_count: 0

      function output() {
         global_num3++;

         alert("local_count:  " + local_count  + "\n" +
               "global_count: " + global_count + "\n" +
               "global_text:  " + global_text
              );

         local_count++; 
      }

      local_count++;
      global_count++;

      return output;  
   }  

   var myFunc = outerFunc();

   myFunc();
      /* Outputs:
       **********************
       * local_count:  1
       * global_count: 1
       * global_text: 
       **********************/

   global_text = "global";
   myFunc();
      /* Outputs:
       **********************
       * local_count:  2
       * global_count: 1
       * global_text:  global
       **********************/

   var local_count = 100;
   myFunc();
      /* Outputs:
       **********************
       * local_count:  3
       * global_count: 1
       * global_text:  global
       **********************/


   alert("global_num1: " + global_num1);      // global_num1: 10
   alert("global_num2: " + global_num2);      // global_num2: 0
   alert("global_num3: " + global_num3);      // global_num3: 33

</script>

我从中取出的有趣的东西:

  1. outerFunc 中的警报仅被调用一次,即当outerFunc 调用分配给 myFunc (myFunc = outerFunc())。这个分配似乎使outerFunc保持打开状态,我称之为持久状态。

  2. 每次调用myFunc时,都会执行return。在本例中,返回值是内部函数。

  3. 真正有趣的是定义局部变量时发生的本地化。请注意第一个警报中 global_num1 和 global_num2 之间的差异,即使在尝试创建变量之前,global_num1 也被视为未定义,因为“var”用于表示该函数的局部变量。 -- 之前已经讨论过,按照 Javascript 引擎的操作顺序,很高兴看到它投入工作。

  4. 全局变量仍然可以使用,但局部变量将覆盖它们。请注意,在第三次 myFunc 调用之前,创建了一个名为 local_count 的全局变量,但它对内部函数没有影响,该函数具有一个同名的变量。相反,每个函数调用都能够修改全局变量,如 global_var3 所注意到的。

发表想法: 尽管代码很简单,但它对你们来说却充满了警报,因此您可以即插即用。

我知道还有其他闭包的示例,其中许多使用匿名函数与循环结构相结合,但我认为这对于 101 初学者课程来说有利于看到效果。

我担心的一件事是闭包会对内存产生负面影响。因为它保持函数环境打开,所以它也将这些变量存储在内存中,这可能/可能不会影响性能,特别是在 DOM 遍历和垃圾收集方面。我也不确定这在内存泄漏方面会起到什么样的作用,并且我不确定是否可以通过简单的“delete myFunc;”从内存中删除闭包。

希望这对某人有帮助,

vol7ron

Question:
There seem to be many benefits to Closures, but what are the negatives? Additionally, is my understanding of Closures correct? Finally, once closures are created, can they be destroyed?

I've been reading a little bit about Javascript Closures. I hope someone a little more knowledgeable will guide my assertions, correcting me where wrong.

Benefits of Closures:

  1. Encapsulate the variables to a local scope, by using an internal function.
    The anonymity of the function is insignificant.

What I've found helpful is to do some basic testing, regarding local/global scope:

<script type="text/javascript">

   var global_text  = "";
   var global_count = 0;
   var global_num1  = 10;
   var global_num2  = 20;
   var global_num3  = 30;

   function outerFunc() {

      var local_count = local_count || 0;

      alert("global_num1: " + global_num1);    // global_num1: undefined
      var global_num1  = global_num1 || 0;
      alert("global_num1: " + global_num1);    // global_num1: 0

      alert("global_num2: " + global_num2);    // global_num2: 20
      global_num2  = global_num2 || 0;         // (notice) no definition with 'var'
      alert("global_num2: " + global_num2);    // global_num2: 20
      global_num2  = 0;

      alert("local_count: " + local_count);    // local_count: 0

      function output() {
         global_num3++;

         alert("local_count:  " + local_count  + "\n" +
               "global_count: " + global_count + "\n" +
               "global_text:  " + global_text
              );

         local_count++; 
      }

      local_count++;
      global_count++;

      return output;  
   }  

   var myFunc = outerFunc();

   myFunc();
      /* Outputs:
       **********************
       * local_count:  1
       * global_count: 1
       * global_text: 
       **********************/

   global_text = "global";
   myFunc();
      /* Outputs:
       **********************
       * local_count:  2
       * global_count: 1
       * global_text:  global
       **********************/

   var local_count = 100;
   myFunc();
      /* Outputs:
       **********************
       * local_count:  3
       * global_count: 1
       * global_text:  global
       **********************/


   alert("global_num1: " + global_num1);      // global_num1: 10
   alert("global_num2: " + global_num2);      // global_num2: 0
   alert("global_num3: " + global_num3);      // global_num3: 33

</script>

Interesting things I took out of it:

  1. The alerts in outerFunc are only called once, which is when the outerFunc call is assigned to myFunc (myFunc = outerFunc()). This assignment seems to keep the outerFunc open, in what I would like to call a persistent state.

  2. Everytime myFunc is called, the return is executed. In this case, the return is the internal function.

  3. Something really interesting is the localization that occurs when defining local variables. Notice the difference in the first alert between global_num1 and global_num2, even before the variable is trying to be created, global_num1 is considered undefined because the 'var' was used to signify a local variable to that function. -- This has been talked about before, in the order of operation for the Javascript engine, it's just nice to see this put to work.

  4. Globals can still be used, but local variables will override them. Notice before the third myFunc call, a global variable called local_count is created, but it as no effect on the internal function, which has a variable that goes by the same name. Conversely, each function call has the ability to modify global variables, as noticed by global_var3.

Post Thoughts:
Even though the code is straightforward, it is cluttered by alerts for you guys, so you can plug and play.

I know there are other examples of closures, many of which use anonymous functions in combination with looping structures, but I think this is good for a 101-starter course to see the effects.

The one thing I'm concerned with is the negative impact closures will have on memory. Because it keeps the function environment open, it is also keeping those variables stored in memory, which may/may not have performance implications, especially regarding DOM traversals and garbage collection. I'm also not sure what kind of role this will play in terms of memory leakage and I'm not sure if the closure can be removed from memory by a simple "delete myFunc;."

Hope this helps someone,

vol7ron

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文