用 jQuery Secret 插件隱藏全域變數

一個幫助你在 Javascript 裡隱藏全域變數的 jQuery 插件

jQuery Secret plugin logo

說明

在 Javascript 裡使用全域變數是很不好的習慣. 在同一個頁面裡執行的程式都可以讀寫全域變數. 因此全域變數很容易被覆蓋過去而造成程式碼執行錯誤, 尤其當這個頁面所執行的程式碼不僅僅由一個人所撰寫時更會有這樣的問題. Douglas Crockford’s 在 Yahoo! User Interface Blog (YUIBlog) 的這篇文章有詳細解說. 通常我們可以給一個命名空間來解決這個問題. 以下面的程式碼為例:

    someNamespace = {
      lang : 'en',
      authToken : 'MZB/o2hQ2OxhTVB+dV7UPEjKWeJBNNefCpAn2EnW/Aw=',
      getPhotos : function(){
        // some AJAX function to get photos form server
      },
      updatePhotos : function(){
        // some AJAX function to update photos to server
      }
    };

好多了, 但是還是有問題沒有解決. 這些資料還有函式還是可以被同一頁面的其他程式讀取或覆寫. 在小型的專案中或是在撰寫一個插件時, 我們可以像 jQuery 的寫法一樣把程式碼包在一個匿名函式裡.

    ( function(){
      // all your code goes here
    })();

但是當我們在大型專案中程式碼常常會需要放在不同的模組, 檔案裡. 因此這個技巧就派不上用場了. 這個實用不妨試試這個插件吧 :)

Demo

  • 這裡 檢視這個 demo
  • 原始碼裡也包含了這個 demo 頁面

下載


需求

  • jQuery 1.3.0+

支援瀏覽器


安裝

  • 首先, 確定你使用了一個有效的 DOCTYPE
  • 引用 JS 檔案
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script type="text/javascript" src="path-to-file/jquery.secret.js"></script>

使用方法

語法
儲存資料
  // 'val' can be a string, integer, hash table, array, object
  $.secret( 'in', 'secretName', val );

  // or a function
  $.secret( 'in', 'secretName', function( arg1, arg2, arg3 ){
    // do something here
  });
取出資料
  $.secret( 'out', 'secretName' );
執行函式
  $.secret( 'call', 'secretName', [ arg1, arg2, arg3 ]);
  // or
  $.secret( 'call', 'secretName', arg );
清除資料
  $.secret( 'clear', 'secretName' );
範例程式碼
儲存資料
  $.secret( 'in', 'lang', 'en' );
‘in’, ‘call’, 還有 ‘clear’ 函式可以串接
  $.secret( 'in', 'name', 'Ben' ).
    secret( 'in', 'age', 30 ).
    secret( 'in', 'sport', [ 'basketball', 'baseball' ]),
    secret( 'call', 'showName', $( '#name' )).
    secret( 'clear', 'jobs' );
使用資料; 你也可以在不同檔案裡使用先前儲存的資料.
  var lang = $.secret( 'out', 'lang' );
清除資料
  $.secret( 'clear', 'lang' );
資料格式可以是字串,
  $.secret( 'in', 'username', 'ben' );
整數,
  $.secret( 'in', 'age', 30 );
陣列,
  $.secret( 'in', 'jobs', [
    'f2e', 'rails developer', 'web developer'
  ]);
散列表(hash table),
  $.secret( 'in', 'photos', [
    { id: 1, title: 'Rails Rocks', image_path: 'http://some-where.com/rails-rocks.jpg' },
    { id: 2, title: 'jQuery Rocks', image_path: 'http://some-where.com/jquery-rocks.jpg' },
    { id: 3, title: 'Node.js Rocks', image_path: 'http://some-where.com/node-js-rocks.jpg' }
  ]);
物件,
  $.secret( 'in', 'userInfo', {
    name : 'Ben',
    age : '30',
    city : 'Taipei'
    family : {
      mother : {
        name : 'Ajita',
        age : '62'
      },
      father : {
        name : 'Frank',
        age : '66'
      }
    }
  });
或是函式,
  $.secret( 'in', 'getCheckedVal', function( $checkbox ){
    // 'this' here points to the private $.secret object
    // in this function scope 'this.lang' means $.secret( 'out', 'lang' );
    
    // store 'this' for the inner scope to use
    var self = this;
    // find values of checked checkbox
    $checkbox.filter( ':checked' ).each( function(){
      var $this = $( this );
      // save each of the checked value to $.secret
      self[ $this.attr( 'name' )] = $this.val();
    });
  });
  
  // to use this funciton
  // we can pass arguments in the 3rd parameter
  $.secret( 'call', 'getCheckedVal', $( '#somewhere' ).find( ':checkbox' ));
  
  // create function with multiple arguments
  $.secret( 'in', 'pplDoSomething', function( $ppl, eyes, car, callback ){
    $ppl.find( '.eyes' ).text( eyes );
    $ppl.find( '.car' ).text( car );
    if( callback ) callback.call( this );
  });
  
  // call function with multiple arguments
  $.secret( 'call', 'pplDoSomething', 
    [ $( '#ben' ), 'brown', 'porsche!!!', function(){
      // do something here
      // IMPORTANT 'this' here points to the private $.secret object
    }]);  
基本上你可以儲存任何你想要的東西.

命名空間

$.secret 支援一層命名空間. 大型的應用程式常常需要將程式碼區分模組. 這時候命名空間就派上用場了.

範例程式碼:
  // create a function that generates flickr api sig
  $.secret( 'in', 'FLICKR.apiSig', function( secret, extraParams ){
    // here 'this.defaultParams' equals to 'FLICKR.defaultParams'
    return md5( secret + this.defaultParams.concat( extraParams.split( "&" )).sort().join('').replace( '=', '' ));
  });
  
  // another function for searching images on google
  $.secret( 'in', 'GOOGLE.searchImage', function( args ){
    // do other stuffs here
  }
  
  // assamble your code in the sandbox
  $.secret( 'in', 'SANDBOX.moduleName', function( args ){
    // assamble your code here
  }

Related posts