jquery源码阅读笔记1:自执行匿名函数,兼容commonJs和AMD协议,$符号调用jquery

蛰伏已久 蛰伏已久 2018-05-14

最新想学习一下jquery的源码,由于本人才疏学浅,理解也不深刻,仅作为自己的学习笔记, 望不吝赐教指正

jquery版本:2.2.4

首先看一下jquery最外围代码

(function( global, factory ) {

   if ( typeof module === "object" && typeof module.exports === "object" ) {
      // For CommonJS and CommonJS-like environments where a proper `window`
      // is present, execute the factory and get jQuery.
      // For environments that do not have a `window` with a `document`
      // (such as Node.js), expose a factory as module.exports.
      // This accentuates the need for the creation of a real `window`.
      // e.g. var jQuery = require("jquery")(window);
      // See ticket #14549 for more info.
      module.exports = global.document ?
         factory( global, true ) :
         function( w ) {
            if ( !w.document ) {
               throw new Error( "jQuery requires a window with a document" );
            }
            return factory( w );
         };
   } else {
      factory( global );
   }

// Pass this if window is not defined yet
}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {


//省略中间1万行代码....

// Register as a named AMD module, since jQuery can be concatenated with other
// files that may use define, but not via a proper concatenation script that
// understands anonymous AMD modules. A named AMD is safest and most robust
// way to register. Lowercase jquery is used because AMD module names are
// derived from file names, and jQuery is normally delivered in a lowercase
// file name. Do this after creating the global so that if an AMD module wants
// to call noConflict to hide this version of jQuery, it will work.

// Note that for maximum portability, libraries that are not jQuery should
// declare themselves as anonymous modules, and avoid setting a global if an
// AMD loader is present. jQuery is a special case. For more information, see
// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon

if ( typeof define === "function" && define.amd ) {
   define( "jquery", [], function() {
      return jQuery;
   } );
}



var

   // Map over jQuery in case of overwrite
   _jQuery = window.jQuery,

   // Map over the $ in case of overwrite
   _$ = window.$;

jQuery.noConflict = function( deep ) {
   if ( window.$ === jQuery ) {
      window.$ = _$;
   }

   if ( deep && window.jQuery === jQuery ) {
      window.jQuery = _jQuery;
   }

   return jQuery;
};

// Expose jQuery and $ identifiers, even in AMD
// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
// and CommonJS for browser emulators (#13566)
if ( !noGlobal ) {
   window.jQuery = window.$ = jQuery;
}

return jQuery;
}));

自执行匿名函数

jquery最外围是一个自执行的匿名函数,我们可以在很多js库中看到这种写法。形如以下写法,函数匿名且自动执行,这种写法相当于声明了一个命名空间,因为函数内部声明的变量,作用域只在函数内部。假如我们不这么写,则可能造成多个js文件变量名称冲突。

//形式1
(function() {
    //内部代码...
   })()

//或形式2
!function() {
   //内部代码...
}()

//或形式3
~function() {
   //内部代码...
}()


兼容CommonJs和AMD

为了让js库支持不同的js协议,需要添加兼容性代码

if ( typeof module === "object" && typeof module.exports === "object" ) {
      // For CommonJS and CommonJS-like environments where a proper `window`
      // is present, execute the factory and get jQuery.
      // For environments that do not have a `window` with a `document`
      // (such as Node.js), expose a factory as module.exports.
      // This accentuates the need for the creation of a real `window`.
      // e.g. var jQuery = require("jquery")(window);
      // See ticket #14549 for more info.
      module.exports = global.document ?
         factory( global, true ) :
         function( w ) {
            if ( !w.document ) {
               throw new Error( "jQuery requires a window with a document" );
            }
            return factory( w );
         };
   } else {
      factory( global );
   }
   
  ......
  
  if ( typeof define === "function" && define.amd ) {
   define( "jquery", [], function() {
      return jQuery;
   } );
}

其他js库的兼容性写法

swiper.js

/*===========================
Swiper AMD Export
===========================*/
if (typeof(module) !== 'undefined')
{
    module.exports = window.Swiper;
}
else if (typeof define === 'function' && define.amd) {
    define([], function () {
        'use strict';
        return window.Swiper;
    });
}

iscroll.js

if ( typeof module != 'undefined' && module.exports ) {
   module.exports = IScroll;
} else if ( typeof define == 'function' && define.amd ) {
        define( function () { return IScroll; } );
} else {
   window.IScroll = IScroll;
}

$符号

jquery用起来很简单,只需要一个美元符号既可以,感觉很神奇,实际很简单,声明window的全局变量jQuery和$,指向jQuery函数,我们可以这样window.$("#id")....,只是window可以省略,所以看起来是$("#id"),ps:“$”和“_”是js允许的变量名称,没有什么特别之处,你完全可以换成其他符号,然后用来调用jquery。

window.jQuery = window.$ = jQuery;






分享到

点赞(0)