近來一直利用業餘時間在看jquery2.1.1源碼,大約看了兩千行了。平時看的時候,作了一些筆記,貼出來分享。jquery
1. Array.prototype.slice.call 能夠將僞數組轉化爲真正的數組數組
其實,這裏所謂的「僞數組」就是有length屬性,而且有「0」、「1」、「2」等這些屬性的對象,以下代碼:瀏覽器
var obj = { 0: "A", 1: "B", 2: "C", length: 3 }; var slice = [].slice; console.log(slice.call(obj));
這裏打印的結果就是一個真正的數組:app
另外,咱們平時所寫的 $('div') ,其實也是這種僞數組,能夠看一下:函數
jquery源碼中有一個方法是用來判斷是不是僞數組的,其中就是根據對象是否有length屬性,而且對象的[length - 1]屬性有沒有值,來判斷的。這樣判斷會排除掉一個特殊的類型——String,string有length屬性,可是它的確不是僞數組。this
上面代碼中,slice.call不只能將僞數組轉化成真正的數組,還能想數組的slice同樣,截取元素。以下:spa
打印的結果可想而知:prototype
2. window對象還有一個「window」屬性code
jquery源碼中,判斷一個對象是不是window的時候,用如下方法來判斷:對象
return obj.window === window;
用瀏覽器監測如下window對象的細節,會發現,window對象下確實還有一個window對象,並且是一個無限循環的結構。
3. 快捷方法
第一:
第二:
將一個對象強制轉換爲與之對應的bool類型,可用: !!obj
相反,若是轉換成一直相反的bool類型,可用: !obj
4. === 與 ==
=== 是嚴格相等,不會進行類型轉換,而 == 是不嚴格相等,會進行類型轉換。有些js的書中,建議開發人員永遠不要用 == 或者 != 。
可是jquery源碼中,有用到「==」或者「!=」的狀況 —— 判斷 undefined 和 null 的時候。
5. 重寫了 toString()
有些對象類型重寫了 toString 方法,所以要獲取這個對象的名稱,就不能簡單的用 .toString() ,而是用 Object.prototype.toString.call
var a = [1, 2]; console.log(a.toString()); // 1,2 console.log(Object.prototype.toString.call(a)); // [Object Array]
6. Object( 'str' ) —— String強制類型轉換爲Object
將一個字符串強制類型轉換成object以後,將會返回一個標準的僞數組對象。
Object( 'abc' ) --> String {0: "a", 1: "b", 2: "c", length: 3}
7. jQuery的each函數,最大的優勢
each函數相比於for循環,最大的改進在於封閉了獨立的函數做用域。
先看一段for循環的代碼:
console.log("current this", this); var $divs = $("div"), index = 0, length = $divs.length; for (; index < length; index++) { console.log(index, this); var j = 200; } console.log(j);
打印的結果以下:
打印結果能夠看出:for循環裏面的語句塊,和外面的做用域相同;最可怕的是 for 循環裏面定義的變量,在外面能夠識別。 別傷心,這就是js的一個「特色」。
爲了解決這個問題,咱們再看看each函數的代碼:
console.log("current this", this); var $divs = $("div"); $divs.each(function (index, elem) { console.log(index, this); var x = 100; }); console.log(x);
打印結果以下:
很容易看出,each函數中的做用域,和外部做用域不一樣,並且each函數中定義的變量徹底是局部變量,外面不可獲取。這正式咱們想要的!
另外,你們還肯能會發現,each比較相似與 for ... in 。 for...in 是迭代器模式,比 for(i=0;i<length;i++)要方便不少。可是除了上面提到了做用域以外,each和for...in就徹底同樣了嗎? 固然不是!
以上兩段代碼,結果卻截然不同。爲什麼? 由於 for...in 會遍歷一個對象的隱式原型元素,而 each 則像for(i=0;i<length;i++)同樣中規中矩。
8. call和apply的參數傳遞不一樣
他倆的傳參方式不一樣可能你們都知道,說一個具體的例子吧,jquery中用到的。
var arr = [5, 6, [1, 2], [3, 4]]; console.log(Array.prototype.concat.call([], arr)); // [5, 6, [1, 2], [3, 4]] console.log(Array.prototype.concat.apply([], arr)); // [5, 6, 1, 2, 3, 4]
以上代碼,輸出的結果徹底不同。看明白這一點,才能說明你真正理解了二者傳參的不一樣。
---------------------------------------------------------------
以上是本次所有內容。jquery還會繼續往下看,筆記也會繼續整理。再有新內容,再分享。