2017年8月31日 星期四

[JavaScript] Overloading, arguments

  • JavaScript 
    • 不支源函式 Overloading (多載) 的功能
function UserInfo (){
    console.log('Lyndon, 30');
}

function UserInfo (name){
    console.log(name, '30' );
}

UserInfo();
    • Result:如同 JavaScript 的特性,後面的 function 取代前面的 function
  • JavaScript - arguments 
    • 函數的參數是以類似陣列的物件所維護。在函數內部,如下定位傳遞給函數的參數︰
arguments[i]
    •  i 是參數的順序編號,從 0 開始
    • 使用 arguments.length 來得知實際傳給函數的參數數目

function UserInfo(separator) {
    var result = "";

    for (var i = 1; i < arguments.length; i++) {
        result += arguments[i] + separator;
    }

    console.log(result);

}

UserInfo(',', 'Lyndon', 'Ken', 'May');
UserInfo('|', 'Lyndon', 'Ken', 'May');
UserInfo('-', 'Lyndon', 'Ken', 'May');
    • Result:傳送任意的參數數目給函數
  • 使用 arguments 來解決 Overloading 問題

function UserInfo() {
    if (arguments.length == 0) {
        console.log('Lyndon, 30');
    } else {
        console.log(arguments[0], '30');
    }
}

UserInfo();
UserInfo('Ken');
    • Result:可見兩種不同使用方法的結果

2017年8月30日 星期三

[JavaScript] Registered Event

  • Registered Event (事件註冊),大致分為如下:
    • 使用 attribute 
    • DOM Level 0 事件註冊語法
    • DOM Level 2 事件註冊語法
  • Event 變數
    • 事件處理常式會包含一個區域變數,稱 Event 
    • 透過此變數可取得 Event 物件,此物件包含事件發生時相關資訊
  • attribute 事件註冊
    • button 利用 onclick 註冊事件,當 click 事件發生時,將執行 attribute 的指定程式碼
    • Html Code
<html>

<head>
    
    <title>The HTML5 Herald</head>

<body>
    <input name="BtnAttribute1" type="button" value="BtnAttribute1" onclick="myfunction1(this);" />
    <input name="BtnAttribute2" type="button" value="BtnAttribute2" onclick="myfunction2(event);" />
    <input name="BtnAttribute3" type="button" value="BtnAttribute3" onclick="myfunction3();" />

    <script src="Attribute.js">
</body>

</html>
    • CASE 1
      • function 傳入 this,可成功抓取此物件
function myfunction1(self) {
    console.log(self);
}
    • CASE 2
      • function 傳入 event,可成功抓取 event 事件並且可知到那個物件觸發
function myfunction2(event) {
    console.log(event);
    console.log(event.target.value);
}
    • CASE 3
      • function 沒傳入任何參數,在 function 使用 this,需注意此 this 指向 window
function myfunction3() {
    console.log(this);
}
    • CASE 4
      • onclick 裡面可以放入許多的 function 執行,但可見標籤與程式相依性高,缺少程式就會發生錯誤
<input type="button" name="BtnAttribute4" value="BtnAttribute4" onclick="myfunction4();" />
  • DOM Level 0 事件註冊語法
    • 先找尋要註冊事件的 HTML 項目或物件,接著指派物件事件處理的常式屬性 (Event Handler Property)
    • Html Code
<html>

<html>

<head>
    <meta charset="utf-8">
    <title>The HTML5 Herald< /title>
</head>

<body>
    <input type="button" name="BtnDOMLevel01" id="BtnDOMLevel01" value="BtnDOMLevel01" />
    <input type="button" name="BtnDOMLevel02" id="BtnDOMLevel02" value="BtnDOMLevel02" />
    <input type="button" name="BtnDOMLevel03" id="BtnDOMLevel03" value="BtnDOMLevel03" />
    <script src="DOMLevel0.js">< /script>
</body>

</html>

    • CASE 1
      • function 使用 this,可成功抓取此物件
document.getElementById('BtnDOMLevel01').onclick = function() {
    console.log(this);
}
    • CASE 2
      • function 傳入 event,可成功抓取 event 事件並且可知到那個物件觸發
document.getElementById('BtnDOMLevel02').onclick = function(event) {
    console.log(event);
    console.log(event.target.value);
}
    • CASE 3
      • 物件需要執行兩個不同的事件註冊,發現只會執行一個(後面蓋掉前面),此解決方法需要使用 closure 
document.getElementById('BtnDOMLevel03').onclick = function() {
    console.log('Action 0');
}

document.getElementById('BtnDOMLevel03').onclick = function() {
    console.log('Action 1');
}
  • DOM Level 2 事件註冊語法
    • 定義兩個方法
      • addEventListener:註冊事件
      • removeEventListener:移除事件
      • 第一個參數為事件名稱
      • 第二個參數為事件處理常式
      • 第三個參數為指明事件在 Event Capture (true) 或 Event Bubbling (false) 階段觸發
    • Html Code
<html>

<head>
    <meta charset="utf-8">
    <title>The HTML5 Herald< /title>
</head>

<body>
    <input type="button" name="BtnDOMLevel11" id="BtnDOMLevel11" value="BtnDOMLevel11" />
    <input type="button" name="BtnDOMLevel12" id="BtnDOMLevel12" value="BtnDOMLevel12" />
    <input type="button" name="BtnDOMLevel13" id="BtnDOMLevel13" value="BtnDOMLevel13" />
    <script src="DOMLevel2.js">< /script>
</body>

</html>
    • CASE 1
document.getElementById('BtnDOMLevel11').addEventListener('click', function() {
    console.log(this);
});
    • CASE 2
document.getElementById('BtnDOMLevel12').addEventListener('click', function(event) {
    console.log(event);
    console.log(event.target.value);
    console.log(event.currentTarget);
});
    • CASE 3
document.getElementById('BtnDOMLevel13').addEventListener('click', function() {
    console.log('Action 0');
});

document.getElementById('BtnDOMLevel13').addEventListener('click', function() {
    console.log('Action 1');
});
  • REF
    • 恆逸 - U2750c

2017年8月29日 星期二

[JavaScript] Constructor, Prototype - Inheritance(3)

  • Inheritance (繼承)
    • 物件導向程式語言中,繼承分為兩種
      • interface inheritance (介面繼承):繼承函式的簽名
      • implementation inheritance (實作繼承):繼承實際的方法 (註:Javascript 只支援此)
    • Prototype Chaining
      • 利用 Prototype 搭配建構函式來實作繼承,稱為 Prototype Chaining
      • JavaScript 所有參考型別都是利用 Prototype Chaining 技術繼承 Object 型別
      • JavaScript 中每一個 Constructor 都有一個 Prototype 屬性,其中包含一個 Prototype 物件指回 Constructor
      • 將 Constructor  指向另一個物件型別,將取得此物件型別的 Prototype 與建構函式,形成 Prototype Chaining (如:[JavaScript] Constructor, Prototype (1) 與 [JavaScript] Constructor, Prototype - Object Literal Notation (2) 所使用的方法都為 Prototype Chaining)
var UserInfo = function(Name, Age) {
    this.Name = Name;
    this.Age = Age;
}

UserInfo.prototype.getAge = function() {
    return this.Age;
}

var AdministratorInfo = function(Name, Age, Authority) {
    this.Name = Name;
    this.Age = Age;
    this.Authority = Authority;
}

AdministratorInfo.prototype = new UserInfo();
AdministratorInfo.prototype.constructor = AdministratorInfo;

var aAdministrator = new AdministratorInfo('Lyndon', 30, true);
      • 架構圖
      • Prototype Chaining 問題,當子物件實體建立時,無法傳引數到父建構函式
    • Constructor Stealing 技巧 (也稱做 object masquerading 或 classical inheritance)
      • 子建構函式中,使用 apply,call 或 bind 方法呼叫父建構函式,如此可將父建構函式定義的屬性繼承下來
      •  apply,call 或 bind
        1. 用來改變函數 this 對像的指向
        2. 第一個參數都為 this 指向的對像
        3. 第二個參數後為傳遞參數

var UserInfo = function(Name, Age) {
    this.Name = Name;
    this.Age = Age;
}

UserInfo.prototype.getAge = function() {
    return this.Age;
}

var AdministratorInfo = function(Name, Age, Authority) {
    // Inherits parent's properties 
    // call
    UserInfo.call(this, Name, Age);
    // apply
    //UserInfo.apply(this, [Name, Age]);
    // bind
    //UserInfo.bind(this, Name, Age)();

    this.Authority = Authority;
}

AdministratorInfo.prototype = new UserInfo();
AdministratorInfo.prototype.constructor = AdministratorInfo;

var aAdministrator = new AdministratorInfo('Lyndon', 30, true);
      • 此方法的架構圖,發現父與子的結構中依然存在相同的 Name 與 Age
    • 使用 Object.create
      • 根據特定的 Prototype 來實做 Inheritance (繼承)
var UserInfo = function(Name, Age) {
    this.Name = Name;
    this.Age = Age;
}

UserInfo.prototype.getAge = function() {
    return this.Age;
}

var AdministratorInfo = function(Name, Age, Authority) {
    // Inherits parent's properties 
    // call
    // 調用一個對象的一個方法,以另一个对象替换当前对象
    UserInfo.call(this, Name, Age);
    // apply
    //UserInfo.apply(this, [Name, Age]);
    // bind
    //UserInfo.bind(this, Name, Age)();

    this.Authority = Authority;
}

// Inherits methods
AdministratorInfo.prototype = Object.create(UserInfo.prototype);
AdministratorInfo.prototype.constructor = AdministratorInfo;

var aAdministrator = new AdministratorInfo('Lyndon', 30, true);
      • 架構圖,將 AdministratorInfo prototype 使用 Object.create 取代原本的 prototype
  • REF
    • 恆逸 - U2750c

2017年8月28日 星期一

[JavaScript] Object, Proerty, Encapsulation

  • JavaScript 建立物件的方法
    • 使用 new 運算式
      • new 運算式,跟隨著建構函式  
var userInfo1 = new Object();
userInfo1.Name = 'Lyndon';
userInfo1.Age = 30;
    • 使用 Object Literal Notation 語法
      • CASE 1:
        1. 大括號「{」開始,接著是屬性名稱
        2. 冒號「:」,之後是屬性值
        3. 兩屬性之間使用「,」做區隔

var UserInfo2 = {
    'Name': 'Lyndon',
    'Age': 30
}
      • CASE 2
        1. 令外可利用 Object Literal Notation 語法建立包含預設屬性的物件,使用句點「‧」為物件新增屬性
var UserInfo2 = {}
UserInfo2.Name = 'Lyndon';
UserInfo2.Age = 30;
    • Result:如上列呈現結果
      1. 因此可使用「‧」存取屬性
      2. 令外可使用「[]」存取屬性
        • 屬性名稱不是簡單的識別項
        • 屬性名稱在直行階段才能得知 (因此不推建此使用方法)
  • JavaScript Reference Type (參考型別)
    • Mothed (方法)
      • Mothed (方法)就是 function (函式)

var UserInfo = {
    Name: 'Lyndon',
    Age: 30,
    getAge: function(){
        return this.Age;
    }
}
    • Property:Data Property (資料屬性)
      • 四個 attribute 
var UserInfo = {}
Object.defineProperties(UserInfo, {
    'Name':{
        // 1. 是否可使用 delete 語法刪除
        // 2. 變更屬性 attribute 
        // 3. 將資料屬性變更為 Accessor Property (存取子屬性)
        configurable: false,
        // 指明屬性是否可以搭配 for .. in 語法使用
        enumerable: false,
        // 屬性值是否可以變更
        writable: false,
        // 屬性值
        value: 'Lyndon'
    },
    'Age':{
        configurable: true,
        enumerable: true,
        writable: true,
        value: 30
    }        
});
    • Property:Accessor Property(存取子屬性) 
      • 需先理解 Data Property 與 Encapsulation,下方詳細描述
  • Encapsulation (封裝)
    • 使用 closures 來達到封裝
    • 原則
      • 建構函式宣告變數時,不要使用 this 關鍵字
      • 使用 this 來宣告方法,以讀/寫屬性值
var UserInfo = function(Name, Age){
    // 區域變數
    var _Name = '';
    var _Age = 0;
    // 方法
    this.getName = function(){
        return _Name;
    }
    this.setName = function(Name){
        _Name = Name;
    }
    this.getAge = function(){
        return _Age;
    }
    this.setAge = function(Age){
        if(0 < Age && Age < 100 )
            _Age = Age;
    }
    // 使用方法
    this.setName(Name);
    this.setAge(Age);
}

var UserInfo1 = new UserInfo('Lyndon', 30);
  • Property:Accessor Property(存取子屬性) 
    • 存取物件的資料屬性值,達到 Encapsulation (封裝),定義存取屬性時包含
      • get:function (函式),讀取資料屬性
      • set:function (函式),修改資料屬性

var UserInfo = function(Name, Age) {
    // 區域變數
    var _Name = '';
    var _Age = 0;
    // Object.defineProperties 定義資料屬性
    Object.defineProperties(this, {
        'Name': {
            get: function() {
                return this._Name;
            },
            set: function(Name) {
                this._Name = Name;
            }
        },
        'Age': {
            get: function() {
                return this._Age;
            },
            set: function(Age) {
                if (0 < Age && Age < 100)
                    this._Age = Age;
            }
        }
    });
    // 使用 Accessor Property
    this.Name = Name;
    this.Age = Age;
};

var UserInfo1 = new UserInfo('Lyndon', 30);
  • REF
    • 恆逸 - U2750c

    2017年8月27日 星期日

    [JavaScript] Constructor, Prototype - Object Literal Notation (2)



    function UserInfo(name, age) {
        this.Name = name;
        this.Age = age;
    }
    
    UserInfo.prototype.getAge = function() {
        return this.age;
    }
    
    var user1 = new UserInfo('Lyndon', 30);
    var user2 = new UserInfo('Daisy', 25);
    
      • Object Literal Notation Code
    function UserInfo(name, age) {
        this.Name = name;
        this.Age = age;
    }
    
    UserInfo.prototype = {
        getAge: function() {
            return this.age;
        }
    }
    
    var user1 = new UserInfo('Lyndon', 30);
    var user2 = new UserInfo('Daisy', 25);
    

      • 結果來看都是一樣,但最大的不同在於 Constructor 屬性會指向 Object 而不是 UserInfo 建構函式,因 Prototype 屬性設定為一個物件時,將會蓋掉原來的 Prototype
        • 流程圖:找不到 Constructor,因此往上一層找尋 Constructor,所以才指向  Object
      • 所以須在 Prototype 中,將 Constructor 指回 UserInfo 
      • Code
    function UserInfo(name, age) {
        this.Name = name;
        this.Age = age;
    }
    
    UserInfo.prototype = {
        constructor: UserInfo,
        getAge: function() {
            return this.age;
        }
    }
    
    var user1 = new UserInfo('Lyndon', 30);
    var user2 = new UserInfo('Daisy', 25);
    
        • 流程圖:將 Constructor 指回 UserInfo 
    • REF 
      • 恆逸 - U2750c

    2017年8月26日 星期六

    [JavaScript] Constructor, Prototype (1)

    • Constructor (建構函式)
      • 建立一個新物件 (注:一定要使用 new,要不然會在 window 下建立)
      • 設定新物件的 Constructor 屬性參照到 Constructor Function (注:Constructor 命名時,英文字的第一個字元都以大寫開始)
      • 指派 this 參考到新物件,this 就代表新建立的物件
      • 呼叫 Constructor Function 中的程式碼,設定物件的屬性 (屬性和方法會直接指派給 this 物件)
      • 回傳一個新物件(不必在 Constructor Function 中使用 return 關鍵字回傳物件)
      • Code 
    function UserInfo(name, age){
        this.Name = name;
        this.Age = age;
        this.getAge = function(){
            return this.age;
        };
    }
    //或者
    var UserInfo = function(name, age){
        this.Name = name;
        this.Age = age;
        this.getAge = function(){
            return this.age;
        };
    }
    
    var user1 = new UserInfo('Lyndon', 30);
    var user2 = new UserInfo('Daisy', 25);
    
      • 物件可用利用 instanceof 判斷型別,或者使用 constructor 來查看型別
    • Prototype (類似繼承)
      • 上方的範例,物件中包含 getAge function,但兩物件的 getAge function 卻不一樣
      • 因 Constructor 為一個函式用來建立物件,利用相同的 Constructor 可以建立多個物件,每個物件包含自己的屬性,此每個物件裡的 function 都載入到自己的記憶體,而造成管理上的問題
      • Prototype 可以讓使用相同 Constructor 建立起來的物件,共享 function 程式碼
      • Constructor Function 建立的 JavaScript 物件都有一個 Prototype 屬性,實際上也是一個物件,可以用來新增屬性和方法
      • Code
    function UserInfo(name, age) {
        this.Name = name;
        this.Age = age;
    }
    
    UserInfo.prototype.getAge = function() {
        return this.age;
    }
    
    var user1 = new UserInfo('Lyndon', 30);
    var user2 = new UserInfo('Daisy', 25);
      • 下列結果可看見,getAge function 為相同,且在 user1 prototype 屬性中多了 getAge function
      • 查看 UserInfo 的結構為如下
    • 架構圖
      • Constructor
      • Constructor + Prototype
    • REF 
      • 恆逸 - U2750c

    2017年8月25日 星期五

    [SQL] char, varchar, nchar, nvarchar, ntext

    • 資料庫中可設定字串格式有 char、varchar、nchar、nvarchar 和 ntext,這些格式有何差異
      • char
        • char 存儲定長數據很方便
        • char 欄位上的索引效率級高,如:定義 char(10)那麼不論存儲的數據是否達到了 10 個字節,都要占去 10 個字節的空間
          1. 儲存空間:n Byte
          2. 使用建議:確認一定長度,且只會有英數字
      • var (varchar, nvarchar)
        • 意思是可變動,因欄位長度可變動,所以會額外花費 2Byte 去儲存地址
        • varchar:可變動長度的 char
          1. 儲存空間:(n + 2) Byte  --2Byte記錄地址
          2. 使用建議:長度可變動,且可能會用非英數以外的字元
        • nvarchar:可變動長度的 nchar
          1. 儲存空間:(2 * n + 2) Byte --2Byte記錄地址
          2. 使用建議:長度可變動,且只會有英數字
      • n (nchar, nvarchar)
        • 支援 UNICODE UCS-2 字元,因為萬國編碼(支援中文字),所以 1 字儲存2Byte
        • nchar:固定長度的char
          1. 儲存空間:(2 * n) Byte
          2. 使用建議:確認一定長度,且可能會用非英數以外的字元
        • nvarchar:可變動長度的 nchar
          1. 儲存空間:(2 * n + 2) Byte --2Byte記錄地址
          2. 使用建議:長度可變動,且只會有英數字
      • ntext
        • 可變長度的 UNICODE UCS-2 字元
        • 最大長度為 2^30 - 1 (1,073,741,823) 個字元
        • UNICODE UCS-2 字元,使用 nchar、nvarchar 和 ntext 資料型別來儲存
          1. 資料內容包含的 UNICODE UCS-2 字元個數並不一致 (最多為 4,000),使用 nvarchar
          2. 資料內容每個項目的長度是固定 (最多為 4,000 個 UNICODE UCS-2 字元),請使用 nchar
          3. 若資料行的任何項目長度超過 4,000 個 UNICODE 字元,則使用 ntext

    2017年8月24日 星期四

    [JavaScript] defer, async

    • defer, async
    起緣
    HTML 4.01
    <script defer src="~/Scripts/Lyndon.js"></script>
    
    XHTML 1.0 / 1.1
    <script defer="defer" src="~/Scripts/Lyndon.js"></script>
    
    HTML 5
    <script defer src="~/Scripts/Lyndon.js"></script>
    <script async src="~/Scripts/Lyndon.js" …>
    
      • 一般我們引用外部 javascript  寫法如下:
      <script src="~/Scripts/Lyndon.js"></script>
      
        • 預設引用用法
        • browser 在 html parsing 碰到 script 時會暫停 html parsing ,會先下載 script 和執行 script 後才會繼續往下做 html parsing
        • 如果引用 script 檔案很大或需要執行時間很長,會使畫面卡卡
        • Demo - HTML
      <!DOCTYPE html>
      <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
          <title></title>
          <script src="JavaScript1.js"></script>
          <script src="JavaScript2.js"></script>
          <script src="JavaScript3.js"></script>
          <script>
              console.log("JavaScript");
          </script>
      </head>
      <body>
      </body>
      </html>
        • 上方為簡單的範例,將引用 script  寫至 head 中,script 檔會依據順序下載並執行
        • 通常寫法會將引用 script 寫至 body 最後,因先下載網頁中的圖片與內容為最重要,之後才是執行 script ,當然有些 script 也是必需先讀取 (如:SVG.js)
      • async 屬性
      <script async src="~/Scripts/Lyndon.js"></script>
      
        • async 在碰到 script 時,會開始下載 script 但不會暫停 HTML parsing ,直到 script 下載完,才會暫停 HTML parsing,把 script 執行完,才會繼續做 HTML parsing
        • 引用多個外部的 script 都是使用 async 時,async 並不保證順序性,誰先下載完,誰就會先行執行
        • 使用時機:此 script 和其他的 script 無連帶關係,即不需等待其他的 script 執行完,可獨立作業
        • Demo
      <!DOCTYPE html>
      <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
          <title></title>
          <script async src="JavaScript1.js"></script>
          <script async src="JavaScript2.js"></script>
          <script async src="JavaScript3.js"></script>
          <script async>
              console.log("JavaScript");
          </script>
      </head>
      <body>
      </body>
      </html>
      • defer 屬性
      <script defer src="~/Scripts/Lyndon.js"></script>
      
        • 整個頁面都下載及分析完成後才會執行,類似於將 script 放在頁尾的情況
        • defer 碰到 script 時不會暫停 html parsing 並同時下載 script 直到 HTML parsing 結束後才執行 script。defer 與 async 不同的是把 script 執行 delay 到 HTML parsing 結束後才處理
        • Demo
      <!DOCTYPE html>
      <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
          <title></title>
          <script defer src="JavaScript1.js"></script>
          <script defer src="JavaScript2.js"></script>
          <script defer src="JavaScript3.js"></script>
          <script defer>
              console.log("JavaScript");
          </script>
      </head>
      <body>
      </body>
      </html>
      • 結論
        • 良好的寫作習慣,還是將 script 寫至  body 最後
        • Demo
      <!DOCTYPE html>
      <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
          <title></title>
      </head>
      <body>
          ...
          ...
          <script defer src="JavaScript1.js"></script>
          <script defer src="JavaScript2.js"></script>
          <script defer src="JavaScript3.js"></script>
          <script defer>
              console.log("JavaScript");
          </script>
      </body>
      </html>
      

      2017年8月23日 星期三

      [HTML] id, class name

      • id vs class name 詳細的描述
      idclass name
      規則
      id 必需是全文檔唯一 (如:一個頁面 id 不能重覆)
      id 具有唯一性
      name 可以同時對應多個控制元件(如:checkbox 和 radio)
      class 是一個類,適用於可多次重複使用的容器
      用途
      HTML 元素的 Identity,主要是在客户端腳本裡使用獲取提交表單的某表單域信息,作為可與伺服器交互數據的HTML 元素的伺服器端的標示,比如input、select、textarea、框架元素( iframe、frame、 window的名字,用於在其他 frame 或window 指定 target )和button等,這些元素都與表單(框架元素作用於 form 的 target ) 提交有關
      瀏覽器會根據 name 來設定發送到伺服器的 request, 在表單的接收頁面只接收有name的元素,所以賦 ID 的元素通過表單是接收不到值的。 我們可以在伺服器端根據其 Name 通過Request.Params 取得元素提交的值。在 form 裡面,如果不指定name,就不會發送到伺服器端l
      控制項
      <label for="MyInput">My Input</label>
      <input id="MyInput" type="text">
      
      • label 與 form 控制項的關聯
      • for 屬性指定與 label 關聯的元素的 id,不可用 name 替代
      <input type="radio" name="gender" value="male" checked> Male
      <input type="radio" name="gender" value="female"> Female
      
      • radio button 控制項在同一個分組類,check 操作是 mutex,同一時間只能選中一個 radio,這個分組就是根據相同的 name 屬性來實現 
      腳本中獲得對象
      • 腳本中獲得輸入的內容,可以直接以 
      • MyInput.value
        
      • 如果用 DOM
      • document.getElementById("MyInput").value
      • 如果用 name,通常先得到包含控制項的 form,然後從 form 再引用 name,注意這樣得到的是經過計算後將發送給伺服器的值
      • document.forms[0]
      Link

        
        <a href="URL">link</a>
        
      • 如果不用 href 屬性,改用name
      • 
        <a name="PageBottom"></a>
        
      • 獲得了一個頁面 Link
      • 
        <strong><a name="1" id="1"></a>Experience (XP)</strong>
        
      IMG

      • IMG元素和MAP元素之間關聯的時候,如果要定義IMG的熱點區域,需要使用其屬性usemap,使usemap="#name"(被關聯的MAP元素的Name)
      特定元素的屬性

      • attribute,meta 和 param
      • Object 定義參數
      • 
        <PARAM NAME="appletParameter" VALUE="value">
        
      • Meta中
      • 
        <META NAME="Author" CONTENT="Dave Raggett">
        
      createElement
      var input = document.createElement('INPUT');
      input.id = 'myId';
      input.name = 'myName';
      alert(input.outerHTML);
      
      
      <INPUT id="myId">
      
      var input = document.createElement('< INPUT name = "myName">'); 
      input.id = 'myId'; 
      alert(input.outerHTML);
      
      <INPUT id="myId" name="myName">
      
      • HTML元素的 name 屬性在頁面中也可以起那麼一點 id 的作用,因為在 DHTML 對象樹中,我們可以使用document.getElementsByName 來獲取一個包含頁面中所有指定 name 元素的對象數組。
      • name 屬性還有一個問題,當我們動態創建可包含 name 屬性的元素時,不能簡單的使用賦值 element.name = "..." 來添加其 name,而必須在創建 Element 時,使用document.createElement('<element name = "myName"></element>') 為元素添加 name 屬性
      注意事項
      • id 要符合標識的要求,比如大小寫敏感,最好不要包含下劃線 (不兼容 CSS)
      • table、tr、td、div、p、span、h1、li 等元素一般用 id
      • 表單相關的元素也可以賦 id 值, 但為這些元素賦 id 值的時候引用這些元素的方法就要變一下
      • 除去與表單相關的元素,只能賦 id 不能賦 name,這些元素有 body、li、a、table、tr、td、th、p、div、span、pre、dl、dt、dd、font、b 等等
      • 引用元素的方式
      document.formName.inputName // 1
      document.frames("frameName") // 2
      
      • name 基本上沒有什麼要求,甚至可以用數字
      • 引用元素的方式
      document.all.inputID // 1
      document.all.frameID // 2
      
      CSS
      • id 是設置標籤的標識,用於區分不同的結構和內容
      • 用於定義一個元素的獨特的樣式
      • CSS 樣式定義的時候以「#」來開頭命名 id 名稱
      • HTML
      
      <div id="banana"></div>
      
      • CSS
      
      #banana{
      color: lime; 
      background: #ff80c0;
      }
      
      • id 是先找到結構/內容,再給它定義樣式
      • id 通常用於定義頁面上一個僅出現一次的標記
      • 在對頁面排版進行結構化布局時(如:說通常一個頁面都是由一個頁眉,一個報頭< masthead>,一個內容區域和一個頁腳等組成)
      • 使用 id 比較理想,因為一個 id 在一個文檔中只能被使用一次,而這些元素在同一頁面中很少會出現大於一次的情況
      • id 在一個頁面中僅能被使用一次
      • id 對宏觀布局和設計放置各種元素較有用
      • 有可能在很大部分瀏覽器中反覆使用同一個id不會出現問題,但在標準上這絕對是錯誤的使用,而且很可能導致某些瀏覽器的現實問題
      • class 是設置標籤的類,用於指定元素屬於何種樣式的類
      • CSS 樣式中以小寫的「.」來命名
      • HTML
      
      <div class="banana"></div>
      
      • CSS
      
      .banana{
      color: lime; 
      background: #ff80c0;
      }
      
      • class 先定義好一種樣式,再套給多個結構/內容
      • class 用來根據用戶定義的標準對一個或多個元素進行定義
      • 一個文檔中使用任意次數的 class
      • class 可以反覆使用
      • class 對文字的排版等比較有用
      相同名稱問題
      • 如果頁面中有n(n>1)個HTML元素的id都相同了怎麼辦?
      • DHTML 對象中怎麼引用他們呢?
        • 使用 ASPX 頁面,這樣的情況是不容易發生,因為 asp.net 進程在處理 aspx 頁面時根本就不允許有 id 非唯一,這是頁面會被拋出異常而不能被正常的render
      • 但如果不是動態頁面,我們硬要讓 id 重複那IE怎麼做呢? 
        • 這個時候我們還是可以繼續使用document.getElementById 獲取對象,只不過我們只能獲取 id 重複的那些對象中在 HTML Render 時第一個出現的對象
        • 這時重複的 id 會在引用時自動變成一個數組,id 重複的元素按 Render 的順序依次存在於數組中,數組的腳下標依次表示 id 出現的先後順序
      • 當然HTML元素的name屬性在頁面中也可以起那麼一點id的作用,因為在 DHTML 對象樹中,使用document.getElementsByName 來獲取一個包含頁面中所有指定 name 元素的對象數組

      2017年8月22日 星期二

      [T-SQL] Temporary Tables

      • Temporary Table(臨時表)

        • 適用於複雜或重覆的子查詢,如果有 1,000 萬筆的資料表,而只需要其中的 1萬筆,並且需重覆的篩選、比對 (Join) 這 1萬筆資料,Temporary Table 能減少重複查詢這龐大資料次數,可讓資料篩選與比對變得更迅速
        • CASE 1 (Temporary Table)
        Create Table #TempTable ( Name varchar(50), Age int )
        
          • 建立一個區域性的暫存資料表 (Local) 
          • 存在 tempdb 資料庫中,建立一個名稱為 #TempTabel 的資料表 (位於暫存資料表中)
          • 這個暫存資料表只有建立者可以使用,其他人可以看到,但無法存取
          • 利用 DROP TABLE 來明確卸除暫存資料表,否則當建立該暫存資料表的連線結束時,SQL Server 會自動將其刪除
        • CASE 2 (Table Variables - SQL Server 2000)
        DECLARE @TmpTable TABLE ( Name varchar(50), Age int )
        
          • 建立一個 TABLE 資料型別的暫存資料表
          • 完全存在於記憶體中,且不會存在於 tempdb,因此其他人無法看到
          • 當定義 TABLE 資料型別的函數、預存程序或批次結束時,就會自動清除這個暫存資料表,不須手動去 DROP
      • 主要使用大多為 CASE 1 (Temporary Table) 方法,因使用上比較方便,Temporary Table需知下列資訊:
        • TABLE NAME 前加入 「#」,表示這是一個 Temporary Table
        • Session 關閉時,這個 TABLE 將會自動  DROP
        • Temporary Table 使用完畢後, 下指令去 DROP,而不是讓系統自動回收
        • Temporary Table 存在主機記憶體中,因此存取速度較快
        • Temporary Table 存在於 tempdb 這個 database 裡 
        • 如果有兩個使用者建立同一個名字的 Temporary Table,則他們會各自擁有獨立的一份,互相不會干擾
        • 若 stored procedure A 建立了一個 Temporary Table,並呼叫 stored procedure B,則在 B 中可以存取這個 Temporary Table
        • 如果 SQL Server Management Studio or Query Analyzer 中建立的 Temporary Table,會等到手動 DROP 去關閉 Session 才會消失
        • Temporary Table Code
        
        USE [LyndonDB]
        GO
        SET ANSI_NULLS ON
        GO
        SET QUOTED_IDENTIFIER ON
        GO
        -- =============================================
        -- Author:    Lyndon
        -- Create date: 2017-08-23
        -- =============================================
        ALTER PROCEDURE [dbo].[SP_TemporaryTable](
          @MinAge int,
          @MaxAge int
        )
        AS
        
        BEGIN
        -- CREATE TemporaryTable
        SELECT 
            Name,
            Age
            INTO #temp
        FROM tblUserInfo
        WHERE (Age BETWEEN @MinAge AND @MaxAge)
        
        -- USE TemporaryTable
        SELECT AVG(Age) AS AVGAge
        FROM #temp 
        
        -- DROP TemporaryTable
        DROP TABLE #temp
        END
         

      • Temporary Table / Table Variables 使用時機

        • 當暫存的資料筆數小於100筆,使用 Table Variables,否則使用 Temporary Table,因為針對 Table Variables,SQL Server 不會去解析/最佳化它的效能
        • 當我們須要對表格建立索引(Index)時,則必須使用 Temporary Table 
        • 使用 Temporary Table 時,最好能在建立後並建立索引,這能增加效能 (SQL Server 2005後,這方面已改善,所以可以不建索引,但建立它仍是一個好習慣)

      • Global Temporary Tables (全域暫存表) 

        • 在表格名字前面,加入兩個「##」(如:##gtemp),則表示這是個全域暫存表,也就是說,這個表格和一般表格一樣,可以被所有連線 (connections/sessions) 使用,在SQL Server 中,這樣的應用並不多見

      • REF:

      2017年8月21日 星期一

      [C#] Dapper using sql file

      • 因許多人在查尋 SQL 會使用組字串或者變數的方式來進行查尋
        • Code-組字串
        
                    StringBuilder sb = new StringBuilder();
                    sb.Append("SELECT ");
                    sb.Append("* ");
                    sb.Append("FROM ");
                    sb.Append("UserInfo");
        
        • Code-變數
        
                static string sqlQuery
                {
                    get
                    {
                        return "SELECT * FROM UserInfo";
                    }
                }
        • 目前查尋都是簡短,需要使用複雜的查尋或者其他行為,會使得 SQL 語法變得非常長,且不容易閱讀
      • 此使用 Resource File  的特性,進行改善此方法
        • 加入 Resources 資料夾在專案中
        • 加入 sql 的檔案,並輸入 SQL 語法
        • 將此檔案加入 Resource File
        • Demo Code
        
            class User
            {
                public string Name { get; set; }
                public int Age { get; set; }
            }
        
            class Program
            {
                static void Main(string[] args)
                {
                    List<user> lUser = null;
        
                    using (SqlConnection con = new SqlConnection(Info.LyndonliuConnectionString))
                    {
                        lUser = con.Query<user>(
                           Properties.Resources.ActionUserInfo,
                           commandTimeout: 0).ToList();
                    }
                }
            }
        
      • 如需撰寫複雜的 SQL 語法(如:當資料存在進行修改,資料不存在進行新增)
        • SQL Code - 修改 ActionUserInfo.sql 如下
        
        -- EXISTS
        IF EXISTS
          (SELECT *
           FROM UserInfo
           WHERE Name = @Name)
        -- UPDATE
        UPDATE UserInfo
        SET Age = @Age
        WHERE Name = @Name;
        ELSE
        -- INSERT
        INSERT INTO UserInfo
        VALUES (@Name,
                @Age);
        
        • C# Code
        
            class User
            {
                public string Name { get; set; }
                public int Age { get; set; }
            }
        
            class Program
            {
                static void Main(string[] args)
                {
                    User user = new User { Name = "Lyndon", Age = 31 };
        
                    using (SqlConnection con = new SqlConnection(Info.LyndonliuConnectionString))
                    {
                        DynamicParameters Param = new DynamicParameters();
                        Param.Add("@Name", user.Name, dbType: DbType.String);
                        Param.Add("@Age", user.Age, dbType: DbType.Int32);
        
                        int count = con.Execute(
                           Properties.Resources.ActionUserInfo,
                           Param,
                           commandTimeout: 0);
                    }
                }
            }
        
      • 此方法雖然簡化許多,並且使 SQL語法是可以閱讀,但開發者需知道 SQL 語法所撰寫的地方,才能進行修改

      2017年8月20日 星期日

      [JavaScript] ES5: Closure, Immediately Invoked Functions(IIFE)

      • ES 5 版本的規格,在 ES 6 可以使用 Let 來解決 Closure 的問題
      • Closure 
        • JavaScript function 可當一個值使用,因此 function 當回傳值是很普遍
        • JavaScript 變數的生命周期是存活在宣告 function  中,當 function 回傳值為 function  或者 object,而此 object 定義 function,這樣就形成 Closure,延長區域的變數生命周期
        • Case 1
        
        // 缺點 result 為全域變數
        var result = 0;
        
        function add (x, y) {
            result = (x + y);
            console.log(result);
        };
        
        add(10, 20);
        add(20, 30);
        add(30, 40);
        
        • Case 2
        
        // 使用 function 封裝,使 result 為區域變數
        function closureAdd() {
            var result = 0;
            
            function add (x, y) {
                result = (x + y);
                console.log(result);
            };
        
            add(10, 20);
            add(20, 30);
            add(30, 40);
        }
        
        closureAdd();
        
        • Case 3 - Closure
          • 使用巢狀式解決全域變數問題
          • 函數當值
        
        // 當函數的回傳值為 function,會形成 "Closure"
        // 延長區域變數的生命週期
        function closureAdd() {
            var result = 0;
            
            function add (x, y) {
                result = (x + y);
                console.log(result);
            };
        
            return add;
        }
        
        var add = closureAdd();
        
        add(10, 20);
        add(20, 30);
        add(30, 40);
        
        • Case 4 - Closure 簡化
        
        function closureAdd() {
            var result = 0;
        
            return function (x, y) {
                result = (x + y);
                console.log(result);
            };;
        }
        
        var add = closureAdd();
        
        add(10, 20);
        add(20, 30);
        add(30, 40);
        
      • Immediately Invoked Functions (IIFE)
        • 通常 function 都是被叫用後才執行 (ex: add())
        • IIFE 定義之後,馬上就會執行 function 
        • JavaScript 區域變數有效範圍 (Scope) 在 function 中,因變數宣告在 IIFE 中,可以避免區域變數命名與全域變數的名稱衝突問題
        • Case 5 - Closure, Immediately Invoked Functions
        
        var add = function () {
            var result = 0;
        
            return function (x, y) {
                result = (x + y);
                console.log(result);
            };;
        }();
        
        add(10, 20);
        add(20, 30);
        add(30, 40);