在介绍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)