自執行函數,判斷在什麼端,若是在瀏覽器端就執行factory函數css
//(function(){a,b})(a,b) //jq大架構,閉包,自執行函數,傳入函數參數(factory:工廠模式) (function(global,factory){ "use strict" //嚴格模式 if(typeof module ==="object" && typeof module.exports ==="object"){ //說明支持CommonJS模塊規範的(例如Node) //... }else{ //瀏覽器端 // factory(window) => 就是傳入的函數參數執行 => function( window, noGlobal){ // window === window noGlobal === undefined(由於執行這個函數的時候,沒有傳第二個參數) //} factory(global); } })(typeof window !== "undefined" ? window : this ,function( window, noGlobal){ }) /* 參數一: typeof window !== "undefined" ? window : this 區分在瀏覽器端運行仍是Node端運行 typeof xx 若是xx不存在,不會報錯,而是返回undefined(js中的暫時性死區問題) typeof window !== "undefined" 這個成立,則他在瀏覽器端或者webView端(瀏覽器端存在window),不存在說明是Node端運行,this代指當前Node模塊 =>第一個參數就是讓global知道是在什麼端運行的 參數二:factory爲一個函數 function( window, noGlobal){} */
factory爲自執行函數傳入的參數,而且在判斷爲瀏覽器端後執行,而且傳入window對象 factory(global)node
(function(global,factory){ factory(global); }) (typeof window !== "undefined" ? window : this ,function( window, noGlobal){ // $() jQ選擇器 //由於window.jQuery = window.$ = jQuery,因此咱們$()執行的就是這個函數 var jQuery = function(selector,context){ return new jQuery.fn.init(selector,context) } //---------------------------each jQuery.fn.each =function (callback){ //jQuery.each(jQ實例,callback) return jQuery.each(this.callback); }; jQuery.each = function(obj,callback){ //obj能夠是數組(類數組) 或者 對象 =>用來遍歷它們 } //-------------------------extend向jq和jq原型上擴展方法 //=>向原型擴展方法是給jq實例用的,通常應用於jq插件封裝 //=>向jq對象中擴展的方法是爲了完善類庫 //$.fn.extend({}) $.fn.extend(true,{}) jQuery.extend = jQuery.fn.extend = function(){ } //--------------------------jQuery是一個類,它的原型上放了好多屬性和方法 jQuery.fn = jQuery.prototype = { //保證原型對象上的構造函數完整性 constructor : jQuery, //... }; //init 也是一個類 //new jQuery.fn.init(selector,context) => $()選擇器是建立這個類的一個實例,因此$()就能夠調用init原型上的方法 //實例本應該指向init.prototype,可是咱們讓init.prototype =jQuery.prototype,因此最終類的init實例的__proto__指向的是jQuery.prototype,也就是相似於建立了一個jQ類的實例 => $()jQ選擇器就是jQ類的一個實例,此實例能夠調取JQ原型上的方法 var init = jQuery.fn.init=function(selector,context){ //.... } init.prototype = jQuery.fn = jQuery.prototype; //衝突處理的( noConflict無衝突) =>$.noConflict() //一個項目中引入了多個類庫,其中一個類庫(例如:zepto)用的也是$=>$===Zepto,此時若是也導入了JQ,那麼$到底表明誰就衝突了 //假設zepto先引入,jq後引入,咱們就把$的使用權給zepto,而後函數中又return了jquery //因此,若是有衝突的時候,咱們能夠 let j = $.noConflict(); 之後 j 就代替了$ var _jQuery = window.jQuery, _$ = window.$; jQuery.noConflict = function(deep){ if(window.$ === jQuery){ window.$ = _$; } if(deep && window.jQuery ===jQuery){ window.jQuery = _jQuery } return jQuery } //這裏爲factory的函數體 //若是是瀏覽器端運行,條件成立 !undefined if(!nonoGlobal){ //把jQuery或者$暴露到全局對象中(這樣當外部引用了jquery的時候,就能夠直接調用裏面定義的方法) window.jQuery = window.$ = jQuery } }) //=>jQ選擇器其實就是把jQuery方法執行 //$() =>function(selector,context){} 讓他執行 //$('.box')獲取當前頁面中樣式類爲box的盒子(範圍/上下文:整個頁面) //$('.banner .box')獲取.banner的盒子後代爲.box的盒子 => 等價於$('.box',document.getElementById('banner'))
$([selector]) [selector]支持三種類型 "string" => 基於css選擇器獲取元素 (底層都是使用正則來一點一點匹配的) 元素節點 => 把DOM元素轉換爲jQ對象 (jQ類的實例) 函數 => $(document).ready(函數) 1.傳css選擇器爲常見用法 2.傳節點,經常使用於將dom對象轉換爲jq對象,方便調用jq內置方法 let boxList = document.querySelectorAll('.box') let $boxList = $(boxList) //轉換爲jq對象 let box1 = $boxList[0] //將jq對象轉換爲原生dom,jq對象 3.傳函數經常使用於開頭,代碼都再傳入的函數中編寫 $(function(){ //等價於 $(document).ready(函數) 當整個頁面的DOM結構加載完成 })
//$('.box')每一次執行都是建立一個JQ的新實例(jQ對象) // => $('.box') !== $('.box') 兩個不一樣的實例,開闢了兩個堆內存 let $box = $('.box'); $('.box').click(()=>{}) $('.box').addClass() $('.box').fadeIn() //這樣雖然能實現效果可是,開闢了三個堆內存,消耗性能,因此咱們應該儘可能用一個變量來接收,用這個變量區操做屬性 $box.click(()=>{}) $box.addClass() $box.fadeIn() //在控制檯輸出jQuery.fn能夠查看原型上的方法,這些方法均可以被實例所調用(此時把jq看做一個類) //獲取一個實例,再使用dir查看 let $box = $('.box') console.dir($box) //但jq也是一個普通對象,再普通對象上也有不少方法,這些方法和實例沒有直接的關係,基於$.xxx()調用,例如:$.Callbacks() 或者 $.ajax() 等 console.dir(jQuery) --------------------------------------------------------- //向jquery原型中拓展方法 $.fn.extend({ aaa(){ console.log('a') } }) ------------------------------------------------------------ //each (當返回值爲false的時候,結束循環,forEach不支持) // => $.each($('.box'),function(){}) // 等價於$('.box').each(function(){}) $.each([10,20,30],function(item,index)=>{}) //不能用箭頭函數,沒有this $.each({age:10,name:小黃},function(key,value){ //參數順序和數組的forEach是相反的 //this => value })