zoukankan      html  css  js  c++  java
  • Closure在JavaScript中的应用

    >
    Closure在JavaScript中的应用

        最近一直抽出时间在看《精通JavaScript》,我觉得这本书的内容丰富程度、深度及涵盖面不亚于《JavaScript高级程序设计》。由于该书的作者也是开源JavaScript框架jQuery的创造者,所以其构建JS框架的设计理念始终贯穿本书。另外该书的另一大特点就是详细介绍了JavaScript中的一些鲜为人知的特性和实践技巧,非常适合那些想要由JavaScript初学者进阶为JavaScript高手的朋友。

        该书中提到了Closure(闭包)的概念,虽然其他的JavaScript书籍也有提到过Closure,但是我发觉看完本书后方能真正理解Closure的精髓。首先来明确一下Closure的概念:Closures are means through which inner functions can refer to the variables present in their outer enclosing function after their parent functions have already terminated.我的理解为:闭包意味着包含在外层函数里面的(内部)函数可以引用到外层函数中所定义的变量,即使外层函数的生命周期已经停止。

        这对我们来说是非常有用的:

    • 利用这种特性可以减少代码量,使代码更简洁明了。举一个例子,我们想让一个函数延迟一定毫秒后执行,并输出一定的信息,那么我们可能会编写这样的代码:

          // Define
          var msg = 'some messsage';
          // Initialize a callback that will occur in one second
          setTimeout(function(){
            // alert msg after 1000 milliseconds
            alert(msg);
          }, 1000);

          上面的代码看起来很乱,不怎么舒服。首先,我们定义一个全局变量msg,这样做很容易和其他的代码或
          JavaScript发生冲突或混淆;其次,上面的代码不够灵活,比如说间隔时间。而利用Closure就可以很轻
          松的解决上面的问题:

          function delayedAlert( msg, time ) {
            // Initialize an enclosed callback
            setTimeout(function(){
              // Which utilizes the msg passed in from the enclosing function
              alert( msg );
            }, time );
          }

    • 结合JavaScript的函数作用域(Function-Scoped)特性和匿名函数(Annoymous Function)可以是代码冲突降至最低(此法甚妙!).

          首先解释一下JavaScript的函数作用域特性,因为在JavaScript中不存在块作用域,这个和C/C++语言是
          不一样的,仅在函数中声明的函数才具有局部作用域。因此下面的代码中的if语句块中所声名的变量val
          实际上就全局变量val:

          // define a global var
          var val = 'some_value';
          // redefine val in if block
          if (true) var val = 'new_value';
          // they are the same reference of the global variable val
          // result is false.
          alert(val == 'some_value');

          其次解释一下匿名函数,没有指定函数名称的函数均可称为匿名函数,而JavaScript语法中也允许将一
          个匿名函数赋给一个变量,如:

          var fnFoo = function() {
            // do something
          };
          // call function
          fnFoo();
          结合大括号就可以构造一个自调用函数(self-executing function),代码如下:

          (function() {
            // do something
          })();

         在结合之前的“函数作用域”特性就可以构造出来可以避免命名冲突的代码,如下:

         // declare a global var
         var vGlobal = 'some_value';
         (function() {
           var vGlobal = 'your_value';
         })();
         // this time return true value with no naming conflict
         alert(vGlobal == 'some_value');

        这个就是我从《精通JavaScript》的Closure小节中体会到的我认为在代码实践中非常有用的技巧。据说很多JavaScript框架(包括jQuery和YUI等)均采用了此法来消除命名冲突的问题。

  • 相关阅读:
    IOS7 UI设计的十大准则
    IOS8-人机界面指南
    Android应用切换皮肤功能实现
    Android 打造自己的个性化应用(五):仿墨迹天气实现续--> 使用Ant实现zip/tar的压缩与解压
    Android 打造自己的个性化应用(四):仿墨迹天气实现-->自定义扩展名的zip格式的皮肤
    Android 打造自己的个性化应用(三):应用程序的插件化
    Android 打造自己的个性化应用(二):应用程序内置资源实现换肤功能
    Android 打造自己的个性化应用(一):应用程序换肤主流方式的分析与概述
    Android防止内存泄漏以及MAT的使用
    Android内存泄漏监测(MAT)及解决办法
  • 原文地址:https://www.cnblogs.com/objectorl/p/1632727.html
Copyright © 2011-2022 走看看