jquery源码分析
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可。
前段时间上班无聊之时,研究了下jquery的源码。现在记录下自己的成果,分享一下。
下面是我自己琢磨和编写的jquery模型,里面有我所写的注释。
/*
* my-jquery-1.0
*/
/*
* 网上也有很多实现的版本,不过这是我在我自己的理解下写的,加上注释,希望可以解释清楚。
*/
/*
* 整个jquery包含在一个匿名函数中,专业点叫闭包,就是下面的形式,如(function(window,undefined){}(window))。
* 闭包的定义在这里不太容易讲清楚,我只说下这样说的好处。
* 1.使整个jquery中定义的变量成为局域变量,不会影响全局变量,个人觉得这也是jquery被成为轻量级的原因之一。
* 2.增加jquery运行速度,因为局域变量运行速度高于全局变量。
* 3.就像你看到,传入的window和undefined,可以自定义名字,方便编写。当然,现在你看到的仍是原来的写法,但是你可以看看jquery的min版本,一定是压缩的。
*/
(function( window, undefined ) {
var
/*jquery的定义,我们平时用的$和jQuery就是它。这里可以看出来真正的jQuery的对象是init方法产生的。
*这样做采用了工厂模式,创建jQuery对象时不需要再new一个对象了。所以你可以发现,我们创建jQuery对象的方式是$(selector)或者是jQuery(selector)
*原版的jQuery定义方法多了个上下文参数context,此处我省略了。
*/
jQuery = function(selector){
return new jQuery.fn.init(selector);
},
/*
* 引用数据、对象以及字符串的方法
*/
core_push = Array.prototype.push,
core_slice = Array.prototype.slice,
core_indexOf = Array.prototype.indexOf,
core_toString = Object.prototype.toString,
core_hasOwn = Object.prototype.hasOwnProperty,
core_trim = String.prototype.trim;
/*
* jQuery对象的定义,这里去掉了所有的属性,只留下了init()。
* jQuery的选择器采用了Sizzle,这里省略了,可以看出我只简单的返回了一个查询ID的方式。
* jQuery的对象并不是这样简单的赋给了对象的一个属性,而是创建了一个数组。在这里忽略那些,只是赋给了obj属性。
* 这里jQuery将原型赋给了jQuery的fn属性,所以我们如果要给jQuery对象扩展,只需要对jQuery.fn扩展就行。
*/
jQuery.fn = jQuery.prototype = {
init:function(selector){
this.obj = window.document.getElementById(selector);
return this;
}
};
/*
* 将jQuery的原型赋给init,这样是为了可以让jQuery对象,也就是init对象可以使用jQuery的扩展方法。
*/
jQuery.fn.init.prototype = jQuery.fn;
/*
* jQuery的扩展方法,这个是jQuery的原版方法,我没做更改。
* 方法的逻辑在这里不再说明,方法的效果就是,我们使用jQuery.extend可以扩展jQuery,而jQuery.fn.extend可以扩展jQuery对象。
*/
jQuery.extend = jQuery.fn.extend = function() {
var options, name, src, copy, copyIsArray, clone,
target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = false; // Handle a deep copy situation
if ( typeof target === "boolean" ) {
deep = target;
target = arguments[1] || {};
// skip the boolean and the target
i = 2;
} // Handle case when target is a string or something (possible in deep copy)
if ( typeof target !== "object" && !d.isFunction(target) ) {
target = {};
} // extend jQuery itself if only one argument is passed
if ( length === i ) {
target = this;
--i;
} for ( ; i < length; i++ ) {
// Only deal with non-null/undefined values
if ( (options = arguments[ i ]) != null ) {
// Extend the base object
for ( name in options ) {
src = target[ name ];
copy = options[ name ]; // Prevent never-ending loop
if ( target === copy ) {
continue;
} // Recurse if we're merging plain objects or arrays
if ( deep && copy && ( d.isPlainObject(copy) || (copyIsArray = d.isArray(copy)) ) ) {
if ( copyIsArray ) {
copyIsArray = false;
clone = src && d.isArray(src) ? src : []; } else {
clone = src && d.isPlainObject(src) ? src : {};
} // Never move original objects, clone them
target[ name ] = d.extend( deep, clone, copy ); // Don't bring in undefined values
} else if ( copy !== undefined ) {
target[ name ] = copy;
}
}
}
} // Return the modified object
return target;
};
/*
* 这里实现了简单的ready绑定序列。
*/
jQuery.extend({
isReady:false,//文档加载是否完成的标识
readyList:[],//函数序列
//以下为工具方法,可忽略
isArray : Array.isArray || function( obj ) {
return jQuery.type(obj) === "array";
}, isWindow : function( obj ) {
return obj != null && obj == obj.window;
}, isNumeric : function( obj ) {
return !isNaN( parseFloat(obj) ) && isFinite( obj );
}, type : function( obj ) {
return obj == null ?
String( obj ) :
class2type[ core_toString.call(obj) ] || "object";
}, isPlainObject : function( obj ) {
// Must be an Object.
// Because of IE, we also have to check the presence of the constructor property.
// Make sure that DOM nodes and window objects don't pass through, as well
if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
return false;
} try {
// Not own constructor property must be Object
if ( obj.constructor &&
!core_hasOwn.call(obj, "constructor") &&
!core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
return false;
}
} catch ( e ) {
// IE8,9 Will throw exceptions on certain host objects #9897
return false;
} // Own properties are enumerated firstly, so to speed up,
// if last one is own, then all properties are own. var key;
for ( key in obj ) {} return key === undefined || core_hasOwn.call( obj, key );
},
isFunction : function(obj){
if(obj && typeof obj == 'function'){
return true;
}
return false;
},
//onload事件实现
ready : function(fn){
//如果是函数,加入到函数序列
if(fn && typeof fn == 'function' ){
jQuery.readyList.push(fn);
}
//文档加载完成,执行函数序列。
if(jQuery.isReady){
for(var i = 0;i < jQuery.readyList.length ;i++){
fn = jQuery.readyList[i];
jQuery.callback(fn);
}
return jQuery;
}
},
//回调
callback : function(fn){
fn.call(document,jQuery);
}
});
//模拟实现jQuery的html方法
jQuery.fn.extend({
html : function(html){
if(html && typeof html == 'string'){
this.obj.innerHTML = html;
return this;
}
return this.obj.innerHTML;
}
});
//导出对象
window.$ = window.jQuery = jQuery;
//判断加载是否完成
var top = false;
try {
top = window.frameElement == null && document.documentElement;
} catch(e) {}
if ( top && top.doScroll ) {
(function doScrollCheck() {
try {
top.doScroll("left");
jQuery.isReady = true;
jQuery.ready();
} catch(e) {
setTimeout( doScrollCheck, 50 );
}
})();
}
}(window));
下面这个是测试文件。
<html>
<head>
<script src="my-jquery-1.0.js" type="text/javascript"></script>
<script type="text/javascript">
$.extend({
testExtend:function(){
alert('extend success');
}
});
$.ready(function(){
alert($("test").html());
$.testExtend();
});
$.ready(function(){
$("test").html("modify success");
});
$.ready(function(){
alert($("test").html());
});
</script>
</head>
<body>
<div id="test">jquery src</div>
</body>
</html>
两个文件复制出来放在同一个文件夹下面,就可以看到效果。希望各位有不同意见的可以提出来一起探讨。
jquery源码分析的更多相关文章
- jQuery源码分析系列
声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...
- [转] jQuery源码分析-如何做jQuery源码分析
jQuery源码分析系列(持续更新) jQuery的源码有些晦涩难懂,本文分享一些我看源码的方法,每一个模块我基本按照这样的顺序去学习. 当我读到难度的书或者源码时,会和<如何阅读一本书> ...
- jQuery 源码分析 8: 回头看jQuery的构造器(jQuery.fn,jQury.prototype,jQuery.fn.init.prototype的分析)
在第一篇jQuery源码分析中,简单分析了jQuery对象的构造过程,里面提到了jQuery.fn.jQuery.prototype.jQuery.fn.init.prototype的关系. 从代码中 ...
- [转]jQuery源码分析系列
文章转自:jQuery源码分析系列-Aaron 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAaro ...
- jquery源码分析之一前言篇
1.问:jquery源码分析的版本是什么? 答:v3.2.1 2.问:为什么要分析jquery源码? 答:javascript是一切js框架的基础,jquery.es6.vue.angular.rea ...
- jQuery源码分析-each函数
本文部分截取自且行且思 jQuery.each方法用于遍历一个数组或对象,并对当前遍历的元素进行处理,在jQuery使用的频率非常大,下面就这个函数做了详细讲解: 复制代码代码 /*! * jQuer ...
- jQuery源码分析系列(转载来源Aaron.)
声明:非本文原创文章,转载来源原文链接Aaron. 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAa ...
- jQuery源码分析系列——来自Aaron
jQuery源码分析系列——来自Aaron 转载地址:http://www.cnblogs.com/aaronjs/p/3279314.html 版本截止到2013.8.24 jQuery官方发布最新 ...
- jQuery源码分析系列(36) : Ajax - 类型转化器
什么是类型转化器? jQuery支持不同格式的数据返回形式,比如dataType为 xml, json,jsonp,script, or html 但是浏览器的XMLHttpRequest对象对数据的 ...
- jQuery源码分析-01总体架构
1. 总体架构 1.1自调用匿名函数 self-invoking anonymous function 打开jQuery源码,首先你会看到这样的代码结构: (function( window, und ...
随机推荐
- windows 下my.ini的配置优化
线上有若干WIN环境下的MySQL,需要进行优化配置,列出以下参数方便查阅 # For advice on how to change settings please see # http://dev ...
- python模块调用
1.某个模块1被调用到另一个模块2的时候,当不想模块1中的某些代码在模块2中执行时,可以在模块一种添加如下代码: if __name__ == "__main__" ...
- Java读写文件方法总结
Java读写文件方法总结 Java的读写文件方法在工作中相信有很多的用处的,本人在之前包括现在都在使用Java的读写文件方法来处理数据方面的输入输出,确实很方便.奈何我的记性实在是叫人着急,很多时候既 ...
- 第二篇 :微信公众平台开发实战Java版之开启开发者模式,接入微信公众平台开发
第一部分:微信公众号对接的基本介绍 一.填写服务器配置信息的介绍 登录微信公众平台官网后,进入到公众平台后台管理页面. 选择 公众号基本设置->基本配置 ,点击“修改配置”按钮,填写服务器地址( ...
- Busybox下mdev配置说明
[TOC] mdev说明 mdev是busybox自带的一个简化版的udev,适合嵌入式应用场合.其具有使用简单的特点.它的作用就是在系统启动和热插拔或动态加载驱动程序时,自动产生驱动程序所需要的节点 ...
- MSDE简介
MSDE的全程是Microsoft SQL Server Desktop Engine,它是一个基于 SQL Server 核心技术构建的数据引擎.MSDE 2000 支持单处理器和双处理器,是面向小 ...
- C++ enum
为啥需要枚举类型 编程语言中的所有特性都是为了满足某种需求,达到某个目的还出现.不会莫名其妙的出现在那. 枚举可以用来保存一组属性的值.enum的全称是enumeration意思是列举 看着这句话可能 ...
- java使用HttpClient传输json格式的参数
最近的一个接口项目,传的参数要求是json,需要特殊处理一下. 重点是这两句话: httpPost.setHeader("Content-Type", "applicat ...
- 快速熟悉Zbrush中的四种裁切笔刷
ZBrush 4.0R4完善了裁切的功能.捷就可以把模型想要隐藏的地方用选择裁切的方法隐藏掉,其中ZBrush在®4.0R4软件中提供了4中裁切笔刷,分别为ClipCircle笔刷.ClipCircl ...
- 实习小记-python中不可哈希对象设置为可哈希对象
在这篇之前,我又专门翻译过官方python3.3的可哈希对象文档,大家可以先参考一下: 实习小记-python中可哈希对象是个啥?what is hashable object in python? ...