[TOC]
选择的jQuery版本是v3.4.1,源码地址
js目录下:
-
jQueryOriginal.js是下载过来的源码
-
jQuery.js是删除原来的英文注释,增加了自己的中文注释的源码
- 这里的注释会逐渐完善,其中的内容也会总结在这个文档里
index.html:
- 用于一些测试以及debug
( function( global, factory ) {
...
} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
...
}
代码开头就是一个立即执行函数,可以防止代码冲突和污染全局环境
两个参数:global为window对象,factory为需要执行的回调函数
( function( global, factory ) {
"use strict";
if ( typeof module === "object" && typeof module.exports === "object" ) {
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 );
}
} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
...
}
看立即执行函数的内部,主要是判断执行环境是否为CommonJS或类似环境
module和module.exports是CommonJS独有的对象,表示当前模块和对外的接口
- 可以看到,判断CommonJS,主要影响的是factory的第二个参数noGlobal
if ( !noGlobal ) {
window.jQuery = window.$ = jQuery;
}
noGlobal只在factory函数的最后用于判断
如果是CommonJS环境,会用require引用,如果不是,就需要挂载在浏览器的window对象下
这里把jQuery对象和$对象挂载到window对象下,就是我们通常使用的两个对象
代码最后除了判断是否CommonJS环境外,还判断了是否遵守AMD规范
if ( typeof define === "function" && define.amd ) {
define( "jquery", [], function() {
return jQuery;
} );
}
define函数是AMD规范定义的唯一一个API
使用方法:define([module-name?], [array-of-dependencies?], [module-factory-or-object]);
factory函数最终返回的是jQuery对象,我们就来看看jQuery对象的定义
var jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context );
}
这里可以看出,jQuery是一个函数(后面还定义了很多属性,因此jQuery既是函数,又是对象)
两个参数:选择器,上下文,返回一个jQuery.fn.init类型的对象(即以此为构造函数的对象)
参数就体现了我们平时的用法:$(selector)
那么其返回值又有什么意义呢?
先看jQuery.fn是什么
jQuery.fn = jQuery.prototype = {
...
constructor: jQuery,
...
}
prototype 和 __proto__简介 : 1.prototype是函数的属性,__proto__是对象的属性 2.__proto__指向对象的原型对象 作用:当访问一个对象的属性时,如果没有,就会去原型里找 3.prototype指向由这个函数创建的实例的原型对象,即constructor.prototype === __proto__ 作用:由此函数构造的对象,可以有公用的属性和方法,都在prototype里
这里有两个关注点:
jQuery.fn = jQuery.prototype
,jQuery.fn定义为jQuery类型对象(这里指以jQuery为构造器的实例对象,而非jQuery本身)的原型,也就是说,jQuery.fn中定义的所有属性和方法,都是jQuery类型的实例对象所共有的constructor: jQuery
,jQuery.fn的构造器时jQuery,也就是说jQuery.fn本身也是jQuery类型的对象
从上一节,我们知道jQuery.fn就是jQuery类型的对象,那么它的init函数又构造了怎样一个对象呢
先看看init本身作为一个普通的函数,是什么样的:
var init = jQuery.fn.init = function( selector, context, root ){
...
}
说实话看不出什么,就比jQuery本身多了一个参数
再看看后面对init有什么操作吧
init.prototype = jQuery.fn;
就在init的定义之后,出现了这一句话
回顾一下,jQuery.fn = jQuery.prototype
说明,由jQuery构造的对象,其原型为jQuery.fn
这里init.prototype = jQuery.fn
,说明由init构造的对象,其原型也为jQuery.fn
而jQuery.fn是一个jQuery类型的实例对象,所以init类型和jQuery类型的对象有共同的原型jQuery.fn
-
jQuery().__proto__ = jQuery.fn
-
jQuery作为函数所返回的实例对象,可以使用jQuery.fn中的属性和方法(共有),也可以使用其构造函数init中定义的属性和方法(私有)