在介绍JQuery框架实现原理之前我们先抛出几个问题,然后在讲解JQuery框架的源码,对问题逐一解答。
1、为什么可以在window下面直接使用$和jQuery就能够调用JQuery框架?
2、在使用JQuery框架的时候我们并没有显示的执行JQuery?
3、JQuery内部是怎样组织的呢?
下面是JQuery1.6中简化了的主要框架代码,如下:
/*! * jQuery JavaScript Library v1.6.2 * https://jquery.com/ * * Copyright 2011, John Resig * Dual licensed under the MIT or GPL Version 2 licenses. * https://jquery.org/license * * Includes Sizzle.js * https://sizzlejs.com/ * Copyright 2011, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * * Date: Thu Jun 30 14:16:56 2011 -0400 */ (function( window, undefined ) { // Use the correct document accordingly with window argument (sandbox) var document = window.document, navigator = window.navigator, location = window.location; var jQuery = (function() { // Define a local copy of jQuery var jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' return new jQuery.fn.init( selector, context, rootjQuery ); }, // Map over jQuery in case of overwrite _jQuery = window.jQuery, // Map over the $ in case of overwrite _$ = window.$, // JSON RegExp(JSON正则表达式) rvalidchars = /^[\],:{}\s]*$/, rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, // Useragent RegExp(浏览器检测正则表达式) rwebkit = /(webkit)[ \/]([\w.]+)/, ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, rmsie = /(msie) ([\w.]+)/, rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, // Keep a UserAgent string for use with jQuery.browser // 用户代理信息,用来判断浏览器版本 userAgent = navigator.userAgent, ... // [[Class]] -> type pairs class2type = {}; jQuery.fn = jQuery.prototype = { constructor: jQuery, init: function( selector, context, rootjQuery ) { ... }, // Start with an empty selector selector: "", // The current version of jQuery being used jquery: "1.6.2", // The default length of a jQuery object is 0 length: 0, ready: function( fn ) { ... }, ... // For internal use only.(只提供内部使用) // Behaves like an Array's method, not like a jQuery method. push: push, sort: [].sort, splice: [].splice }; // Give the init function the jQuery prototype for later instantiation jQuery.fn.init.prototype = jQuery.fn; })(); ... // Expose jQuery to the global object // 将jQuery暴露给window,然后就可以在window作用域中通过$或者jQuery调用 window.jQuery = window.$ = jQuery; })(window);
从上面JQuery框架的部分源码可以看出,JQuery框架的实现模式如下(回答问题3):
(function(window){ var JQuery = function(){ ... }; JQuery.fn = JQuery.prototype; JQuery.fn.m1 = function(){ ... 方法 ... }; window.jQuery = window.$ = JQuery; })(window);
仔细看上面的代码你会发现,这不是"构造函数+原型"的方式来创建对象吗?的确是这样的,这就是JQuery的主要实现思路,但是这是JQuery的一个轮廓,其中还包含很多细节和重要的实现思想,我讲在后序博文中介绍。
下面就回答了1和2两个问题:
// 能够不许要手动调用jquery的初始方法就能使用$,使用了函数表达式,如下: (function(window){ var JQuery = function(){ ... }; // 将JQuery对象放到window作用域中,通过$或jQuery访问(问题1) window.jQuery = window.$ = JQuery; })(window); // 上面代码会自动执行,为什么? // 函数的声明如下: function test(){ ... } test(); // 等价 var test = function(){ ... }; test(); // 等价 var test = (function(){ ... }); test(); // 等价 (function(){ ... })(); // 避免了var语句,且已经在运行时自动调用了(问题2)