2015年8月31日 星期一

好用的Google JavaScript 瘦身器

我們在做網站開發時,通常會用到很多JavaScript的檔案,而可能會佔上專案的不少空間,這時就會有把JavaScript裡的內容進行編碼瘦身的需求,經過編碼後,JavaScript裡的一些變量、函式名等之類的值都會度換成沒有意義的文字,並且縮排、換行會全部被取消,所以編碼後的檔案容量大小可以大幅度地被減少。

網路上有許多的JavaScript瘦身器,這裡介紹一個好用的Google JavaScript 瘦身器,可以幫助我們對JavaScript檔進行編碼。

Closure Compiler
它有提供多種編碼的方式,例如線上貼上代碼進行編碼,或是用它提供的API來以程式的方式進行編碼等,下圖為線上貼上代碼進行編碼的擷圖:

其他的JavaScript瘦身器資料:

  1. 5 Excellent JavaScript Minification Tools to Improve your Code's Performance
  2. JS & CSS Minifier (Jane Marie Shepard 網友推薦)

2015年8月27日 星期四

JavaScript的同名函式問題及輸入參數的陣列特性

最近在工作中發現了一個以前沒有注意到的問題,找到了解決方法及解釋,所以特在此做了一個紀錄。

在Java中,很多人都應該有同名函式,不同函式簽名的多載Overload概念,但是在JavaScript中,是不能把這樣的觀念一併套用的。

我們來看一下以下的程式碼:
<html>
<body>

<script type="text/javascript">
function foo(a) {
   alert('foo(a) is called!');
}
function foo(a,b,c) {
    alert('foo(a,b,c) is called!');
}
foo('a');
</script>

</body>
</html>

如果有寫過Java但不熟JavaScript的話,很容易就會想說跳出的視窗應該是 "foo(a) is called!" 的吧,不過事實上並不是這樣的。

事實上跳出的事窗會是 "foo(a,b,c) is called!",也就是說 foo(a) 這個function跟本就沒被呼叫到,很顯然的,JavaScript並不會因為不同的方法簽名呼叫就使用不同方法簽名的方法,也就是沒有Java常見的多載(overload)特性。

其實在JavaScript中,函式的名稱只是一個類似指標(C語言)或參考(Java的reference)的查西,在每一次指定function內容及名稱時,名稱指向的位置都會改變,上述的例子中,第一次foo指向一個function及記憶體位置,而第二次又指向了另外一個function內容及記憶體位置,所以foo(a)就沒用了,最後foo代表的就是foo(a,b,c)。

在JavaScript中,呼叫方法function)時,輸入的參數是以類似陣列的方式傳進方法中的,所以其實方法簽明中的輸入參數個數並不是很重要,甚至可以傳入參數給方法簽名沒有輸入參數的方法(當然在方法簽名上標名變數名稱有利於程式易讀性及使用)。

如以下的程式碼是完全可以成功且正確的執行的:
<html>
<body>

<script type="text/javascript">
function sum() {   
   var inputArguments = sum.arguments;
   var answer = 0;
   for (i=0 ; i < inputArguments.length ; i++){
      answer = answer + inputArguments[i];
   }
   alert('輸入了' + inputArguments.length + '個數字,' + '總合為:' + answer);
}
sum(1);
sum(1,2);
sum(1,2,3);
</script>

</body>
</html>

執行後將可以看到三個視窗跳出來,分別顯示如下文字:
輸入了1個數字,總合為:1
輸入了2個數字,總合為:3
輸入了3個數字,總合為:6

可以發現,在JavaScript中,方法本身其實就像是一個物件,例如在上例中 sum() 本身就像是一個物件,可以用sum.arguments來存取輸入的參數,而輸入的參數也是像一個物件,可以存取其length及各元素的值。

而也因為 sum 就代表名為 sum 的方法,所以如果我們用方法的名稱去宣告一個新變數是會發生問題的,例如像下面這個例子,就會發生 TypeError: Cannot read property 'arguments' of undefined 的錯誤 ,因為此時sum()代表呼叫sum函式,而使用了 var sum=0 時,sum.arguments.length的sum變成指向一個sum()中的sum屬性了,所以是還沒defined的(這時真正執行的順序是var sum; --> alert(sum.arguments.length); --> alert(sum); 請參考 "Javascript的變量聲明提昇"):

<html>
<body>

<script type="text/javascript">
function sum() {   
    try{
       alert(sum.arguments.length);  //這裡的sum是指sum()中的sum屬性,但因沒有定義而會出錯
       var sum = 0;
       alert(sum);
    }catch(error){
       alert(error);
    }
}
sum(1,2); //加括號時,sum指的是名為sum的function
</script>

</body>
</html>

那正確的寫法是什麼呢?事實上argument這個屬性是可以直接在function裡使用而不用在前面特別指定function名稱的,所以這樣寫就不會報錯了:
<html>
<body>

<script type="text/javascript">
function sum() {   
    try{
       alert(arguments.length);
       var sum = 0;
       alert(sum);
    }catch(error){
       alert(error);
    }
}
sum(1,2);
//輸出為:
//2
//0
</script>

</body>
</html>


如果這樣的話,也就是沒有下var sum=0,即沒有跟sum()的名稱衝突的話,也是可以的,此時sum就是function了
<html>
<body>

<script type="text/javascript">
function sum() {   
    try{
       alert(arguments.length);
       var sum2 = 0;
       alert(sum);
    }catch(error){
       alert(error);
    }
}
sum(1,2);
//輸出為:
//2
//function sum() {   
//    try{
//       alert(arguments.length);
//       //alert(typeof(sum));
//       var sum2 = 0;
//       alert(sum);
//    }catch(error){
//       alert(error);
//    }
//}
</script>

</body>
</html>

參考資料:
  1. Javascript同名函式
  2. The arguments array- the secret to robust functions

2015年8月23日 星期日

Google Analytics API的使用

Google Analytics 是 Google 的一個服務,可以幫助開發者來追蹤分析網站的流量、來源、訪問的瀏覽器等資料,Google提供了一個親切的可視化管理介面,並且可以在上面設置各種功能及觀看報表。

但是對於開發者來說,這樣的服務開不夠,開發者有可能會希望利用程式的方式進行Google Analytics 的追蹤查詢,所以Google又提供了Google Analytics API 的服務,讓開發者可以如使用Java等方式用程式來訪問Google Analytics。

最近在工作時,發現Google Analytics API 從2.0版升級到了3.0版本,所以很多以前用2.0版寫的程式都沒辨法跑了,必須要用到3.0版的方式才行。

在這裡我把如何申請Google Analytics及如何使用Google Analytics API做了一個紀錄,以供日後查讀:

一、申請及使用Google Analytics
首先你要先跟Google申請Google Analytics的使用,登入Google Analytics的首頁後,如果是第一次使用Google Analytics,要先設定想要追蹤分析的網頁網址。如果已經設定過了,就會進入報表頁面,如下所示:


按下"管理",可以看到如下畫面,分成"帳戶"、"資源"和"資料檢視"三個部份。

帳戶:為使用Google Analytics的管理者,可以設定不同的權限。

資源:為要追蹤分析的網站、行動應用程式或裝置 (如資訊站或銷售點裝置),在"資源"-->"追蹤資訊"-->"追錝程式碼裡"可以看到Google提供的JavaScript程式碼,需要放到想要追蹤分析的網頁程式碼中。

2015年8月17日 星期一

將Tomcat配置至Eclipse

這裡紀錄了在Eclipse中如何配置Tomcat的步驟:
  1. 配置Server
  2. 在Eclipse的Window-->Preferences-->Server-->Runtime Environments中,將Tomcat設到Server runtime environments中,


    選擇你要設定的Tomcat 版本,


    並選擇Tomcat的根目錄位址


  3. 引入Tomcat的Jar檔
  4. 對專案按右鍵,選擇Properties-->Java Build Path,到Libraries分頁裡面把Tomcat的Jar檔引入進來,如下所示,其中這裡用到了Variable的設置,所以下圖的"TOMCAT_HOME"事實上代表了Tomcat的根目錄位置。





    1. 在Eclipse做Java EE時,要記得把要用到的外步Jar設定到在布署時要放到的地方,如下圖,對專案按右鍵,選擇Deployment Assembly-->Add,再選擇"Java Build Path Entries",然後把引入的Jar選進來,例如下圖設為將外部Jar檔在伂署時放到WEB-INF/lib中,即Tomcat Web規則的位置。
    參考資料:

    1. Eclipse 的 Tomcat 環境設定
    2. JavaWeb:报错信息The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
    3. 新建java Web 出现的问题 球指点 急急!!!!

    解決在Eclipse無法正常顯示Unicode字元的問題(使用Properties Editor插件)

    在使用Eclipse IDE時,有時會碰到Unicode字元無法正常地顯示,例如:

    "即將推出"       變成      "\u5373\u5c07\u63a8\u51fa"

    這時只要使用Properties Editor這個插件(Plug-In)就可以很好地解決這個問題,下面就詳述解決的步驟:


    在Eclipse中,在上方選單中按下 Help-->Install New Software


    接著按下 "Add" 按鈕,在 "Add Repository"視窗中的 "Location" 打上 插件的位置 "http://propedit.sourceforge.jp/eclipse/updates/ (現在改成這個了: https://free.nchc.org.tw/osdn//storage/g/p/pr/propedit/eclipse/updates/site.xml)" , "Name" 可自取,最後按下 "OK"。




    此時會出現可供下載的Properties Editor選項,最下面的為最新版,其他的是之前的版本。



    按著按下 "Finish" 後將其按裝完成。

    此時會需重新啟動Eclipse,之後就會發現所有有Unicode內容的Property檔案左邊出現了 綠色的"P"圖案,如下所示:
    這樣之後打開檔案就可以正常顯示Unicode字元了,當然你也可以對檔案按右鍵用"Open With"選傳統的Text Editor來看原始的字元編碼內容。


    2015年8月2日 星期日

    Spring的注解(Annotation)事務(Transaction)範例與JUnit測試(Spring+Hibernate+JUnit)

    此篇文以一個簡單完整的範例,來說明在Spring中如何使用注解(Annotation)事務(Transaction)與其要注意的事項,並且以JUnit來測試

    首先我們要下載 aopalliance.jar ,不然在執行事務時可能會發生ClassNotFoundException。可以到The Central Repository中搜尋最新版的jar,這是因為aopalliance.jar已經從NetBeans內建的Spring中分離了出來,要自已手動下載並引入至Library。如下圖:

    在這裡,我們想要設計的構想其專案配置如下:
    詳述如下:

    1. DaoClass.java:操控資料庫的CRUD(新增、查詢、修改、刪除)之Class。
    2. Guest.java:代表資料庫中的資料表之ORM(Object-Relational Mapping) 物件。
    3. ServiceClass.java:使用DaoClass進行事務(Transaction)處理的Class。
    4. DaoTest.java:用來測試DaoClass的測試JUnit。
    5. ServiceTest:用來測試ServiceClass的測試JUnit。
    在這裡,Guest代表的Table設計如下圖所示(在此例中Table中不用儲任何紀錄,這裡只是做個示範):


    首先是在applicationContext.xml中配置要給Spring托管的內容,如連線池、SessionFactory、Annotation的支持設定、自動裝配Bean等等: