2011年12月27日 星期二

[筆記]Javascript Patterns 一些好習慣 -- for loops

for Loops

1: // sub-optimal loop

   2: for (var i = 0; i < myarray.length; i++) {
   3:     // do something with myarray[i]
   4: }
   5:  
   6: //應使用下面的寫法
   7: for (var i = 0, max = myarray.length; i < max; i++) {
   8:     // do something with myarray[i]
   9: }

如果要套上剛剛所說的 single var 的寫法的話



   1: function looper() {
   2:     var i = 0,
   3:         max,
   4:         myarray = [];
   5:     // ...
   6:     for (i = 0, max = myarray.length; i < max; i++) {
   7:         // do something with myarray[i]
   8:     }
   9: }

還可以更簡單嗎?? 下面只用到兩個變數



   1: function foo(){
   2:     var myarray = [],
   3:         i = myarray.length;
   4:     while(i--){
   5:         // do something with myarray[i]
   6:     }
   7: }


for-in Loops



for-in loops 大部份是用在不是 array 的物件身上,雖然也可以用在 Array 上,但並不建議。


在使用上可以用 hasOwnProperty(i) 來過濾物件屬性。如下面的  code 該物件有一個 clone() 的 function,就可以用 hasOwnProperty 來將其濾除



   1: // the object
   2: var man = {
   3:     hands: 2,
   4:     legs: 2,
   5:     heads: 1
   6: };
   7: // somewhere else in the code
   8: // a method was added to all objects
   9: if (typeof  Object.prototype.clone === "undefined") {
  10:     Object.prototype.clone = function () {};
  11: }
  12:  
  13: // 1.
  14: // for-in loop
  15: for (var i in man) {
  16:     if (man.hasOwnProperty(i)) { // filter
  17:         console.log(i, ":", man[i]);
  18:     }
  19: }
  20: /*
  21: result in the console
  22: hands : 2
  23: legs : 2
  24: heads : 1
  25: */
  26: // 2.
  27: // antipattern:
  28: // for-in loop without checking hasOwnProperty()
  29: for (var i in man) {
  30:     console.log(i, ":", man[i]);
  31: }
  32: /*
  33: result in the console
  34: hands : 2
  35: legs : 2
  36: heads : 1
  37: clone: function()
  38: */

 

不要用 eval()


這個應該不用多說, eval 會有潛在的安全性問題。


parseInt() 的注意事項


如果使用者輸入日期格式的文字在要 parseInt 的值時,在 舊版本的 javascript 會將該文字當作 8 進位來計算,會造成錯誤。所以在用 parseInt 時要指定 radix 的值



   1: var month = "06",
   2:     year = "09";
   3: month = parseInt(month, 10);
   4: year = parseInt(year, 10);

在大多數的狀況下也可以用下面的方式



   1: +"08" // result is 8
   2: Number("08") // 8

雖然速度會比較快一點,不過因為 parseInt 還做了 parse 的動作,所以像 “08 hello” 這樣子的文字還是可以正常的 parse 出來,而 用上面方法的就只會回傳 NaN 了

[筆記]Javascript Patterns 一些好習慣–Global 變數

JSLint

JSLint 來測定你的 javascript 的品質。

The Console

Console 物件並不是 javascript 的一部份,而是屬於 Browser。

Console 物件可以用來 取代 alert()。與其將變數的值alert出來,不如就用 console.log 將值顯示出來吧。(alert 會中斷程式執行)

 

寫 Javascript 的好習慣

Minimizing Globals

javascript 是利用 function 來定義命名空間(scope)。在function 裡定義的變數是 local 變數,在function之外則存取不到。而 global 變數則是存在 function 之外,每一個 global 變數會變成一個global 物件的屬性(property)

   1: myglobal = "hello"; // antipattern
   2: console.log(myglobal); // "hello"
   3: console.log(window.myglobal); // "hello"
   4: console.log(window["myglobal"]); // "hello"
   5: console.log(this.myglobal); // "hello"

使用 global 變數的問題



很容易跟其他人寫的 javascript 發生衝突,而此種衝突是最難發現的,有人在 global 定義了一個變數叫 result 則以下的 code 就會將 result 的值改變,造成潛在的  bug




   1: function sum(x, y) {
   2:     // antipattern: implied global
   3:     result = x + y;
   4:     return result;
   5: }
var 讓 result 這個變數變成 local ,就不會造成  global 的問題



   1: function sum(x, y) {
   2:     // antipattern: implied global
   3:     var result = x + y;
   4:     return result;
   5: }

小心這樣也會變成 global



chain assignments



   1: function foo() {

   2:     // antipattern: do not use
   3:     var a = b = 0;
   4:     // ….
   5: }


上面的 code 等同於 var a = (b = 0);  不小心就多了一個 global 變數,應該改為下面的寫法。




       1: function foo() {
       2:     var a, b;
       3:     // ...
       4:     a = b = 0; // both local
       5: }


如何安全的使用 Global



如果真的必需要使用 global 也請用下面的方式來寫,以提醒自已目前使用的是 global 變數



   1: var global = (function(){return this;}());
   2:  
   3: test1();
   4:  
   5: function test1(){
   6:   global.msg = "this is test 1";
   7:   test2();
   8: }
   9: function test2(){
  10:   console.log(global.msg);
  11:   console.log("msg:" + msg);
  12: }

使用單一 var 來定義變數 (single var)



好處



  • 將所有的變數定義在程式最開始的地方
  • 避免使用到未定義的變數
  • 幫助你記得要定義變數,以避免不小心將變數變成 global
  • 較少的程式碼


   1: function func() {
   2:     var a = 1,
   3:         b = 2,
   4:         sum = a + b,
   5:         myobject = {},
   6:         i,
   7:         j;
   8:     // function body...
   9: }
  10:  
  11: function updateElement() {
  12:     var el = document.getElementById("result"),
  13:         style = el.style;
  14:     // do something with el and style...
  15: }

2011年12月22日 星期四

All-in-One Code Framework 很多 Code Sample 的地方

一直覺得學東西最快的方式就是看人家寫的 sample。Microsoft 推出了這個站 All-in-One Code Framework. 提供了許多的 sample 。而且如果沒有你想要的範例,你還可以提出需求,讓 Microsoft 的工程師幫你寫一個喲。

參考連結:

http://1code.codeplex.com/

2011年12月21日 星期三

Entity Framework with Unity IoC

在使用 EF4.1 及 Unity 時遇到了資料更新後還會取得舊資料的問題。發現原來是因為使用了 Unity 的關係。

Unity 記下了DBContext 的Instance 而不會在每次 request 的時後重新建立。所以會產生取得舊資料的問題。要記得加上 HierarchicalLifetimeManager 才能夠讓 dbContext  在每次 Request 的時後重建。

   1: private static IUnityContainer BuildUnityContainer()
   2: {
   3:     var container = new UnityContainer();
   4:  
   5:     container.RegisterType<ILtsService, LtsService>();
   6:     container.RegisterType<IEmpService, EmpService>();
   7:  
   8:     container.RegisterType<WEKIDSDBEntities>(new HierarchicalLifetimeManager());
   9:     container.RegisterType<CodeGroupHelper>(new PerThreadLifetimeManager());
  10:     container.RegisterType<SeqNoHelper>(new PerThreadLifetimeManager());
  11:     
  12:     container.RegisterInstance<IUnityContainer>(container, new PerThreadLifetimeManager());
  13:     
  14:     container.RegisterControllers();
  15:  
  16:     return container;
  17: }

 


參考資料:


Introducing The Unity.Mvc3 NuGet Package To Reconcile MVC3, Unity and IDisposable