湯姆大叔博客學習筆記(一)

首先湯姆大叔的博客:http://www.cnblogs.com/TomXu/archive/2011/12/15/2288411.html#3346482javascript

筆記:html

  (1)、第一節:java

  一、再循環裏,向下數到0,一般更快,由於和0作比較要比和數組長度或是其餘不是0的東西做比較更有效率編程

var i, myarray = [];
for (i = myarray.length; i–-;) {
   // 使用myarray[i]作點什麼
}

  二、使用parseInt()你能夠從字符串中獲取數值,該方法接受另外一個基數參數,這常常省略,但不該該。當字符串以」0″開頭的時候就有可能會出問 題,例如,部分時間進入表單域,在ECMAScript 3中,開頭爲」0″的字符串被當作8進制處理了,但這已在ECMAScript 5中改變了。爲了不矛盾和意外的結果,老是指定基數參數。數組

 

var month = "06",
    year = "09";
month = parseInt(month, 10);
year = parseInt(year, 10);

  (2)、第二節閉包

  (3)、第三節模塊化

  一、函數

Module模式是JavaScript編程中一個很是通用的模式,通常狀況下,你們都知道基本用法,本文嘗試着給你們更多該模式的高級使用方式。spa

首先咱們來看看Module模式的基本特徵:code

  1. 模塊化,可重用
  2. 封裝了變量和function,和全局的namaspace不接觸,鬆耦合
  3. 只暴露可用public的方法,其它私有方法所有隱藏
var blogModule = (function () {
    var my = {}, privateName = "博客園";

    function privateAddTopic(data) {
        // 這裏是內部處理代碼
    }

    my.Name = privateName;
    my.AddTopic = function (data) {
        privateAddTopic(data);
    };

    return my;
} ());

 

  Module模式的一個限制就是全部的代碼都要寫在一個文件,可是在一些大型項目裏,將一個功能分離成多個文件是很是重要的,由於能夠多人合做易於開發。再回頭看看上面的全局參數導入例子,咱們可否把blogModule自身傳進去呢?答案是確定的,咱們先將blogModule傳進去,添加一個函數屬性,而後再返回就達到了咱們所說的目的

var blogModule = (function (my) {
    my.AddPhoto = function () {
        //添加內部代碼  
    };
    return my;
} (blogModule)); 

  

鬆耦合擴展

  實現Module模式的任意加載順序

var blogModule = (function (my) {

    // 添加一些功能   
    
    return my;
} (blogModule || {})); 

  

緊耦合擴展

  雖然鬆耦合擴展很牛叉了,可是可能也會存在一些限制,好比你沒辦法重寫你的一些屬性或者函數,也不能在初始化的時候就是用Module的屬性。緊耦合擴展限制了加載順序,可是提供了咱們重載的機會

var blogModule = (function (my) {
    var oldAddPhotoMethod = my.AddPhoto;

    my.AddPhoto = function () {
        // 重載方法,依然可經過oldAddPhotoMethod調用舊的方法
    };

    return my;
} (blogModule));  

子模塊

  最後一個也是最簡單的使用方式,那就是建立子模塊

blogModule.CommentSubModule = (function () {
    var my = {};
    // ...

    return my;
} ());

  (4)、第四節

用閉包保存狀態

  和普通function執行的時候傳參數同樣,自執行的函數表達式也能夠這麼傳參,由於閉包直接能夠引用傳入的這些參數,利用這些被lock住的傳入參數,自執行函數表達式能夠有效地保存狀態。

// 這個代碼是錯誤的,由於變量i歷來就沒背locked住
// 相反,當循環執行之後,咱們在點擊的時候i纔得到數值
// 由於這個時候i操真正得到值
// 因此說不管點擊那個鏈接,最終顯示的都是I am link #10(若是有10個a元素的話)

var elems = document.getElementsByTagName('a');

for (var i = 0; i < elems.length; i++) {

    elems[i].addEventListener('click', function (e) {
        e.preventDefault();
        alert('I am link #' + i);
    }, 'false');

}

// 這個是能夠用的,由於他在自執行函數表達式閉包內部
// i的值做爲locked的索引存在,在循環執行結束之後,儘管最後i的值變成了a元素總數(例如10)
// 但閉包內部的lockedInIndex值是沒有改變,由於他已經執行完畢了
// 因此當點擊鏈接的時候,結果是正確的

var elems = document.getElementsByTagName('a');

for (var i = 0; i < elems.length; i++) {

    (function (lockedInIndex) {

        elems[i].addEventListener('click', function (e) {
            e.preventDefault();
            alert('I am link #' + lockedInIndex);
        }, 'false');

    })(i);

}

 

 注:第一種方法沒有綁定的緣由是,由於在for循環裏面指定給list_obj[i].onclick的事件處理程序,也就是onclick那個匿名函數是在for循環執行完成後(用戶單擊連接時)才被調用的。而調用時,須要對變量i求值,解析程序首先會在事件處理程序內部查找,但i沒有定義。而後,又到方法外部去查找,此時有定義,但i的值是4(只有i大於4纔會中止執行for循環)。所以,就會取得該值。

Module模式

// 建立一個當即調用的匿名函數表達式
// return一個變量,其中這個變量裏包含你要暴露的東西
// 返回的這個變量將賦值給counter,而不是外面聲明的function自身

var counter = (function () {
    var i = 0;

    return {
        get: function () {
            return i;
        },
        set: function (val) {
            i = val;
        },
        increment: function () {
            return ++i;
        }
    };
} ());

// counter是一個帶有多個屬性的對象,上面的代碼對於屬性的體現實際上是方法

counter.get(); // 0
counter.set(3);
counter.increment(); // 4
counter.increment(); // 5

counter.i; // undefined 由於i不是返回對象的屬性
i; // 引用錯誤: i 沒有定義(由於i只存在於閉包)
相關文章
相關標籤/搜索