源码链接:内附实例代码

jQuery使用许久了,但是有一些API的实现实在想不通。于是抽空看了jQuery源码,现在把学习过程中发现的一些彩蛋介绍给大家(⊙0⊙)。

下面将使用简化的代码来介绍,主要关注jQuery的实现思想~>_<~

 //匿名立即执行函数
//1.防止污染全局空间
//2.选择性保护内部变量
(function(window, undefined){
//第二参数undefined设置而不传的原因:
// 外部发生这种情况:var undefined = 10时,undefined会被篡改
// 设置第二参数而不传,则undefined就会被重置回原来值 function jQuery(sel){
return new jQuery.prototype.init(sel);
} jQuery.prototype = {
constructor: jQuery,
init: function(sel){
if(typeof sel === 'string'){
var that = this;
//jQuery内部使用的是Sizzle,这里使用querySelectorAll替代
var nodeList = document.querySelectorAll(sel);
Array.prototype.forEach.call(nodeList, function(val, i){
that[i] = val;
})
this.selector = sel;
this.length = nodeList.length;
}
}
} jQuery.prototype.init.prototype = jQuery.prototype; //对外暴露jQuery:将jQuery绑定在window上面
window.$ = jQuery;
})(window);

--------------------------

jQuery一开始使用匿名立即执行函数包裹其内部,并在第5行对外暴露;

所谓的匿名立即执行函数即这个函数是匿名的(没有名字)、定义完后立即调用的;

当我们在外部调用$("div")时,其实调用的就是内部的jQuery("div");

(function(window, undefined){
//内部变量 //对外暴露jQuery:将jQuery绑定在window上面
window.$ = jQuery;
})(window); $("div")

--------------------------

好,接下来稍复杂点,下面的代码主要实现如图的互相引用:

以$('div')调用为例: 

从第2行代码可以看出,jQuery使用jQuery.prototype.init来实例化jQuery对象,但这会带来一个问题:

实例化的对象只能访问到init下的变量,而不能访问到jQuery.prototype(jQuery对外提供的API绑定在该对象下)。

于是乎,补写第21行代码,将init.prototype指向jQuery.prototype即可。

这样就完成了,使用init来实例化,且可以在init作用域下访问到jQuery.prototype。

 function jQuery(sel){
return new jQuery.prototype.init(sel);
} jQuery.prototype = {
constructor: jQuery,
init: function(sel){
if(typeof sel === 'string'){
var that = this;
//jQuery内部使用的是Sizzle,这里使用querySelectorAll替代
var nodeList = document.querySelectorAll(sel);
Array.prototype.forEach.call(nodeList, function(val, i){
that[i] = val;
})
this.selector = sel;
this.length = nodeList.length;
}
}
} jQuery.prototype.init.prototype = jQuery.prototype;

为什么使用jQuery.prototype.init来实例化对象,而不直接使用jQuery函数呢?

假设使用jQuery函数来实例化对象,这样对象之间的引用的确可以简化为 jQuery-->jQuery.prototype。

但是调用会变得繁琐起来:new $('div'),所以基于这个考虑(猜测(⊙0⊙)),在内部使用较为复杂的实现,来简化调用。

--------------------------

好,最后,再来看一下init的实现。同样也简化了代码,只实现了最常用的一种情况。

jQuery会把获取到的nodeList处理成数组(方便后续使用),并在其下挂载一些变量,如length,selector。

 init: function(sel){
if(typeof sel === 'string'){
var that = this;
//jQuery内部使用的是Sizzle,这里使用querySelectorAll替代
var nodeList = document.querySelectorAll(sel);
Array.prototype.forEach.call(nodeList, function(val, i){
that[i] = val;
})
this.selector = sel;
this.length = nodeList.length;
}
}

--------------------------

下一期预告:jQuery的XX如何实现?——2.show与链式调用

ps:代码已经上传到github中了

jQuery的XX如何实现?——1.框架的更多相关文章

  1. jQuery的XX如何实现?——4.类型检查

    往期回顾: jQuery的XX如何实现?——1.框架 jQuery的XX如何实现?——2.show与链式调用 jQuery的XX如何实现?——3.data与cache机制 -------------- ...

  2. jQuery的XX如何实现?——3.data与cache机制

    往期回顾: jQuery的XX如何实现?——1.框架 jQuery的XX如何实现?——2.show与链式调用 -------------------------- 源码链接:内附实例代码 jQuery ...

  3. jQuery的XX如何实现?——2.show与链式调用

    往期回顾: jQuery的XX如何实现?——1.框架 -------------------------- 源码链接:内附实例代码 jQuery使用许久了,但是有一些API的实现实在想不通.于是抽空看 ...

  4. 【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.1.CSS框架和其他功能

    jquery.ui.all.css 1.所有主题必须的文件都包含在这个文件中.它由ui.base.css和ui.them.css两个文件中拉入的@import执行构成. jquery.ui.base. ...

  5. Jquery学习笔记1-jquery总体代码框架

    第一次在博客中记录自己的笔记,希望能坚持下去吧,加油! 今天学习的是Jquery的源代码,官网上下载,然后使用DW(dream waver)编辑器打开Js(下载的是未压缩版),版本是2.0.3.第一次 ...

  6. javascript学习笔记-2:jQuery中$("xx")返回值探究

    最近在写一个jQuery插件的时候,需要用到一个条件: 一组img标签,每一个元素都需要被它前面的元素值src替换,如果是第一个(序列为0)则其值为最后一个元素值,如果是最后一个,那么其值为第一个元素 ...

  7. jQuery源码分析之整体框架

    之前只是知道jQuery怎么使用,但是我觉得有必要认真的阅读一下这个库,在分析jQuery源码之前,很有必要对整个jQuery有个整体的框架概念,才能方便后面对jQuery源码的分析和学习,以下是我总 ...

  8. jQuery Mobile 移动 web 应用程序框架

    在这里我们主要讲一下如何引用jQuery Mobile(引用了jQuery Mobile,你就能引用jQuery Mobile里已经封装好的代码,让开发更加快捷简单) 从 CDN 引用 jQuery ...

  9. 仿照jQuery写一个关于选择器的框架(带了注释,请多多指教~)

    var select = (function () { //这是一个异常与捕获的代码,它表示的意思是:如果push方法出现了错误那么就需要重写push方法 try { //这边是自己模拟一个场景,来使 ...

随机推荐

  1. 编程范式 epesode2 negative values, float 精度

    episode2 //it is very interesting,an excellect teacher,  I love it 1,why negative is indicated the w ...

  2. Ubuntu-12.04-server 配置修改静态 IP地址

    前几天在装Ubuntu 12.04 Server版系统的服务器时IP地址写错了,导致服务器不能上网,今天重新修改了一下IP地址,这里做一个总结. 1.配置静态IP地址 sudo vi /etc/net ...

  3. Looping Techniques

    [Looping Techniques] 1.When looping through dictionaries, the key and corresponding value can be ret ...

  4. delphi之多线程编程

    本文的内容取自网络,并重新加以整理,在此留存仅仅是方便自己学习和查阅.所有代码均亲自测试 delphi7下测试有效.图片均为自己制作. 多线程应该是编程工作者的基础技能, 但这个基础我从来没学过,所以 ...

  5. Python全栈之路6--正则表达式

    正则本身就是一门语言: 正则表达式使用单个字符串来描述.匹配一系列符合某个句法规则的字符串,在文本处理方面功能非常强大,也经常用作爬虫,来爬取特定内容,Python本身不支持正则,但是通过导入re模块 ...

  6. node.js 基础学习 express安装使用

    安装好nodeJs,我们需要使用命令行中安装express. 我这里默认将Node.js安装在C:\Program Files\nodCejs\盘中. 在保持联网的状态下,依次输入如下命令. npm ...

  7. (转)C#中两个问号和一个问号 ??

    小问题难倒很多人.今天发现了这个问题,搜了很长时间才看到记录下. 实例:dt.Columns.Add(firstRow.GetCell(i).StringCellValue ?? string.For ...

  8. SMTP的相关命令

    SMTP是Simple Mail Transfer Protocol的简写. 邮件是日常工作.生活中不能缺少的一个工具,下面是邮件收发的流程. Image 邮件的发送,主要是通过SMTP协议来实现的. ...

  9. SUSE Linux Enterprise Server 11 软件源

    1.添加软件源 zypper ar http://ftp5.gwdg.de/pub/opensuse/discontinued/distribution/11.4/repo/oss oss zyppe ...

  10. Nginx虚拟目录支持PHP配置

    感谢作者:http://blog.csdn.net/fangaoxin/article/details/7030139 location ~ ^/test/.+\.php$ { alias /var/ ...