jQuery架构(源码)分析
( 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 ) {
........
var version = "3.1.1",
/*
* jQuery构造函数创建时直接返回实例对象,此时就不需要
* jQuery = function( selector, context ) {//构造函数 }
* var a = new jQuery( selector, context);
* 而是jQuery( selector, context)就得到一个jQuery初始化实例对象
* 实际上这个构造函数并不是this指向的真实意义上的构造函数,而是工厂方式来创建实例。
*/
jQuery = function( selector, context ) {
//jQuery.fn.init构建的出来的实例对象,就是jQuery对象
//jQuery.fn.init.prototype = jQuery.fn;通过原型传递解决问题,把jQuery的原型传递给jQuery.fn.init.prototype
return new jQuery.fn.init( selector, context ); },
rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
rmsPrefix = /^-ms-/, rdashAlpha = /-([a-z])/g,
fcamelCase = function( all, letter ) { return letter.toUpperCase(); };
/* jQuery原型 * jQuery.fn引用jQuery原型prototype,为jQuery实例添加方法和属性 * 例如,我们常用的$('class').each、$('div').eq(0)、$(arr).push()、$(arr).slice()等 */
jQuery.fn = jQuery.prototype = {
jquery: version,
constructor: jQuery,
length: 0,
toArray: function() { return slice.call( this ); },
get: function( num ) { if ( num == null ) { return slice.call( this ); } return num < 0 ? this[ num + this.length ] : this[ num ]; },
pushStack: function( elems ) { var ret = jQuery.merge( this.constructor(), elems ); ret.prevObject = this; return ret; },
.......
};
/*
* jQuery扩展插件
* jQuery.extend 对jQuery本身的属性和方法进行了扩展
* jQuery.fn.extend 对jQuery.fn的属性和方法进行了扩展
* 两种扩展其实是同一方法不同对象的调用
* eg:
* var obj1 = {alert:function(){}}
* var obj2 = {consoleLog = function(){}}
* jQuery.fn.extend(obj1,obj2)
*/
jQuery.extend = jQuery.fn.extend = function() {
/*
* 形参对象arguments,支持多种参数形式
* eg:
* $.extend(obj1)
* $.extend(obj1,obj2,obj3,......)
* $.extend(true,obj1,obj2,obj3,......)
*/
var options, name, src, copy, copyIsArray, clone,
target = arguments[ 0 ] || {}, //初始化target,target引用形参arguments[0]
i = 1,
length = arguments.length,
deep = false;
//第一个参数为布尔值时,表示是否深度拷贝
if ( typeof target === "boolean" ) {
deep = target; //arguments[0],变量deep表示是否深度拷贝 target = arguments[ i ] || {};
//target去第二个参数,即arguments[1]
i++;
}
if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { target = {}; }
/*
* 如果只参数只传入一个对象时
* target引用this(jQuery.extend 或 jQuery.fn)
* target添加方法就是给this添加方法
* 即将传入对象整合到全局jQuery或jQuery.fn中
*/
if ( i === length ) {
target = this;
i--;
}
for ( ; i < length; i++ ) {
if ( ( options = arguments[ i ] ) != null ) {
for ( name in options ) {
//target继承参数的属性和方法
src = target[ name ];
copy = options[ name ];
if ( target === copy ) {
continue;
}
// 深度拷贝
if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
( copyIsArray = jQuery.isArray( copy ) ) ) ) {
if ( copyIsArray ) {
copyIsArray = false;
clone = src && jQuery.isArray( src ) ? src : [];
} else {
clone = src && jQuery.isPlainObject( src ) ? src : {};
}
target[ name ] = jQuery.extend( deep, clone, copy );
// Don't bring in undefined values
} else if ( copy !== undefined ) {
target[ name ] = copy;
}
}
}
}
// 返回重载合并传入参数后的对象
return target;
};
/*
* 为jQuery对象扩展方法
*/
jQuery.extend( {
isArray: Array.isArray,
isWindow: function( obj ) {
return obj != null && obj === obj.window;
},
isNumeric: function( obj ) {
return ( type === "number" || type === "string" ) &&
!isNaN( obj - parseFloat( obj ) );
},
type: function( obj ) {
if ( obj == null ) {
return obj + "";
}
return typeof obj === "object" || typeof obj === "function" ?
class2type[ toString.call( obj ) ] || "object" :
typeof obj;
},
each: function( obj, callback ) {
var length, i = 0;
if ( isArrayLike( obj ) ) {
length = obj.length;
for ( ; i < length; i++ ) {
if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
break;
}
}
} else {
for ( i in obj ) {
if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
break;
}
}
}
return obj;
},
trim: function( text ) {
return text == null ?
"" :
( text + "" ).replace( rtrim, "" );
},
makeArray: function( arr, results ) {
var ret = results || [];
if ( arr != null ) {
if ( isArrayLike( Object( arr ) ) ) {
jQuery.merge( ret,
typeof arr === "string" ?
[ arr ] : arr
);
} else {
push.call( ret, arr );
}
}
return ret;
},
map: function( elems, callback, arg ) {
var length, value,
i = 0,
ret = [];
if ( isArrayLike( elems ) ) {
length = elems.length;
for ( ; i < length; i++ ) {
value = callback( elems[ i ], i, arg );
if ( value != null ) {
ret.push( value );
}
}
} else {
for ( i in elems ) {
value = callback( elems[ i ], i, arg );
if ( value != null ) {
ret.push( value );
}
}
}
return concat.apply( [], ret );
},
.........
} );
if ( typeof Symbol === "function" ) {
jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
}
.........
jQuery.fn.ready = function( fn ) {
readyList
.then( fn )
// Wrap jQuery.readyException in a function so that the lookup
// happens at the time of error handling instead of callback
// registration.
.catch( function( error ) {
jQuery.readyException( error );
} );
return this;
};
jQuery.parseJSON = JSON.parse;
if ( typeof define === "function" && define.amd ) {
define( "jquery", [], function() {
return jQuery;
} );
}
var _jQuery = window.jQuery,
_$ = window.$;
jQuery.noConflict = function( deep ) {
if ( window.$ === jQuery ) {
window.$ = _$;
}
if ( deep && window.jQuery === jQuery ) {
window.jQuery = _jQuery;
}
return jQuery;
};
........
return jQuery;
} );
整理核心代码
(function(){
//jQuery变量定义
var jQuery = function(){...};
//jQuery原型定义(包含核心方法)
jQuery.fn = jQuery.prototype = {...};
//把jQuery的原型传递给jQuery.fn.init.prototype
jQuery.fn.init.prototype = jQuery.fn;
//提供jQuery静态方法与对象方法的扩展函数
jQuery.extend = jQuery.fn.extend = function(){...};
//后面依次有多个对jQuery静态方法的扩展
jQuery.extend({...});
//后面依次有多个对jQuery对象方法的扩展
jQuery.fn.extend({...});
jQuery.support = (function() {...})();
//提供统一时间管理,jQuery内部使用,并不对外开放
jQuery.event = {...};
//Event类似于Java的POJO类.传递事件的对象
jQuery.Event = function( src, props ) {...};
//Sizzle选择器,一个框架,可独立使用。
(function(){
...
jQuery.find = Sizzle;
...
})();
...
//将定义的jQuery定义为全局变量
window.jQuery = window.$ = jQuery;
...
})();
以上就是jQuery的架构分析,jQuery提供的所有属性方法都是对jQuery对象,jQuery.fn对象的属性和方法进行了扩展
这样的方式便于开发者维护代码,为JQ添加新方法时,不需要修改jQuery的原型,又可以快速扩展JQ功能。也为其他开发者提供了一个扩展接口
以上为本前端菜鸟对jQuery的理解,如有偏颇,欢迎指教。
jQuery架构(源码)分析的更多相关文章
- jQuery.attributes源码分析(attr/prop/val/class)
回顾 有了之前的几篇对于jQuery.attributes相关的研究,是时候分析jQuery.attr的源码了 Javascript中的attribute和property分析 attribute和p ...
- jQuery.queue源码分析
作者:禅楼望月(http://www.cnblogs.com/yaoyinglong ) 队列是一种特殊的线性表,它的特殊之处在于他只允许在头部进行删除,在尾部进行插入.常用来表示先进先出的操作(FI ...
- jQuery.buildFragment源码分析以及在构造jQuery对象的作用
这个方法在jQuery源码中比较靠后的位置出现,主要用于两处.1是构造jQuery对象的时候使用 2.是为DOM操作提供底层支持,这也就是为什么先学习它的原因.之前的随笔已经分析过jQuery的构造函 ...
- jQuery.access源码分析
基本理解 jQuery.attr是jQuery.attr,jQuery.prop,jQuery.css提供底层支持,jQuery里一个比较有特色的地方就是函数的重载, 比如attr,有如下几种重载 $ ...
- EventBus 使用/架构/源码分析
EventBus是针对Android优化的发布-订阅事件总线,简化了Android组件间的通信.EventBus以其简单易懂.优雅.开销小等优点而备受欢迎. github 地址:https://git ...
- jQuery.Deferred 源码分析
作者:禅楼望月(http://www.cnblogs.com/yaoyinglong ) 1 引子 观察者模式是我们日常开发中经常用的模式.这个模式由两个主要部分组成:发布者和观察者.通过观察者模式, ...
- pouch架构源码分析
// daemon/daemon.go 1.func NewDaemon(cfg config.Config) *Daemon 调用containerStore, err := meta.NewSto ...
- jQuery 2.1.4版本的源码分析
jQuery 2.1.4版本的源码分析 jquery中获取元素的源码分析 jQuery.each({// 获取当前元素的父级元素 parent: function(elem) { var parent ...
- jQuery.Callbacks 源码解读二
一.参数标记 /* * once: 确保回调列表仅只fire一次 * unique: 在执行add操作中,确保回调列表中不存在重复的回调 * stopOnFalse: 当执行回调返回值为false,则 ...
- MyBatis 源码分析
MyBatis 运行过程 传统的 JDBC 编程查询数据库的代码和过程总结. 加载驱动. 创建连接,Connection 对象. 根据 Connection 创建 Statement 或者 Prepa ...
随机推荐
- 将传统项目改造为SSM框架的项目
首先 第一步改变传统dao层 先要再resource文件夹下创建一个applicationContext.xml 内容如下 关键代码 <!-- 使spring扫描包下的所 ...
- PHP编辑器PhpStrom运行缓慢问题
最近在使用phpstorm开发项目的时候,在加载文件运行时,不管有多大,如果项目文件数据比较多的话,都能够让phpstorm卡到死机.其中调整过内存设置,关闭过动态提示,使用过phpstorm的安全模 ...
- 《java.util.concurrent 包源码阅读》04 ConcurrentMap
Java集合框架中的Map类型的数据结构是非线程安全,在多线程环境中使用时需要手动进行线程同步.因此在java.util.concurrent包中提供了一个线程安全版本的Map类型数据结构:Concu ...
- 0:A+B Problem-poj
0:A+B Problem 总时间限制: 1000ms 内存限制: 65536kB 描述 Calculate a + b 输入 Two integer a,,b (0 ≤ a,b ≤ 10) 输出 ...
- 算法帖——用舞蹈链算法(Dancing Links)求解俄罗斯方块覆盖问题
问题的提出:如下图,用13块俄罗斯方块覆盖8*8的正方形.如何用计算机求解? 解决这类问题的方法不一而足,然而核心思想都是穷举法,不同的方法仅仅是对穷举法进行了优化 用13块不同形状的俄罗斯方块(每个 ...
- 【转】《高级前端3.6》JavaScript多线程——Concurrent.Thread.js, WebWork
原文链接:http://www.cnblogs.com/woodk/articles/5199536.html JavaScript多线程,在HTML5 WebWork没出现之前很多人都是用Concu ...
- 揭秘 HashMap 实现原理(Java 8)
HashMap 作为一种容器类型,无论你是否了解过其内部的实现原理,它的大名已经频频出现在各种互联网面试中了.从基本的使用角度来说,它很简单,但从其内部的实现来看(尤其是 Java 8 的改进以来), ...
- 享元模式(Flyweight)
享元模式(Flyweight) 享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用. FlyWeightFactory负责创建和管理享元单元, ...
- php编译安装php-5.6
#php编译安装php-5.6 ,Nginx+php使用 #!/bin/sh #php编译安装php-5.6 ,Nginx+php使用 #定义函数,默认绿色输出 '#' 开头为红色 function ...
- DOM操作基本用法
本文列举了js中DOM选取的基本用法,在列表中没有id的情况下如何选取到需要的一项,代码如下: <h2>获取Jerry的js代码</h2> <ul id="fi ...