Jquery這么普及,必有它過人之處,通過開源代碼進行學習,是個不錯的學習方法啊!
(function(){ var _cQuery = window.cQuery, cQuery = function(){ return new cQuery.fn.init(); }; cQuery.fn = cQuery.prototype = { init : function () {
console.log(this); return this; }, test : function () { console.log('test'); } }; cQuery.fn.init.prototype = cQuery.fn; window.C = window.cQuery = cQuery; })(); C().test();
輸出結果
代碼分析
1、把cQuery注冊到window屬性中,當成全局變量使用。用C做為簡易名稱。
window.C = window.cQuery = cQuery;
2、
cQuery.fn.init.prototype = cQuery.fn;
拿圖說話(打印當前對象cQuery):
去掉該句截圖。
填上此句截圖:
難點分析:原型傳遞
init的原型只是當前的函數。
用cQuery.fn.init.prototype = cQuery.fn;覆蓋init構造器的原型對象,從而實現跨域訪問。
評估:
這是一招妙棋,new cQuery.fn.init()創建的新對象擁有init構造器的prototype原型對象的方法,通過改變prototype指針的指向,使其指向cQuery類的prototype。——這樣創建出來的對象就繼承了cQuery.fn原型對象定義的方法。
3、用一個var定義變量,函數。Jquery源碼里用了79行定義了一連串的變量(在開頭部分)。
(function(){ var _cQuery = window.cQuery, cQuery = function(){ return new cQuery.fn.init(); }; cQuery.fn = cQuery.prototype = { init : function () { return this; }, each : function(obj, callback) { // each 方法 var name, length = obj.length; for (name in obj) { if (callback.call(obj[name], name, obj[name]) === false) { break; } } }, isWindow : function(obj) { return obj != null && obj == obj.window; } }; cQuery.fn.init.prototype = cQuery.fn; window.C = window.cQuery =cQuery; })(); C().each({ Height : 'height', Width : 'width'}, function(name, type){ console.log(this, name, type); });
輸出結果
難點分析:callback.call(obj[name], name, obj[name])
callback是function(name, type){ console.log(this, name,type);}這個方法
第一個obj[name]是"height“或"width"字符串,是callback函數里的this。
name,第二個obj[name]是傳給callback的參數。
isWindow : function(obj) { return obj != null && obj == obj.window; }
調用:
console.log(cquery.isWindow(window));
console.log(cquery.isWindow(document));
輸出結果
window對象有一個特殊的屬性window,等價於 self 屬性,它包含了對窗口自身的引用。通過這個屬性判斷是否是window對象!
