车大棒浅谈jQuery源码(二)
前言
本来只是一个自己学习jQuery笔记的简单分享,没想到获得这么多人赏识。我自己也是傻呵呵的一脸迷茫,感觉到受宠若惊。
不过还是有人向批判我的文章说,这是基本知识点,完全跟jQuery源码沾不上边。说jQuery博大精深,还要我静下心来研究, 别净整些没用的。弄的我一脸懵逼,WTF?我从头到尾都没有说我讲的多高端,我连标题都写的“浅谈”。就完全不能让我等菜鸟慢慢先从的简单的入手吗?
但是有位名为“萌新”三好童鞋,就做的非常好。“啪”!,反手就是一拖鞋留言砸过来一串代码。指出说undefined在ES5、ES6标准中只是全局作用域下不能被定义,一旦脱离全局作用域下undefined就能够被定义。
所以希望能够像能够像萌新同学狠狠打脸找知识点错误,而不是指出我这个太简单一类的。这个我本来就是个人学习过程的浅谈一下,给菜鸟一点活路吗!
原型prototype
我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。
--《高级程序第三版》-6.23 原型模式
这里我引用了高级程序第三版当中的一段话用来简单描述原型prototype,但是这个玩意具体有什么用?
解释何为原型之前, ⾸先看下⾯的代码:
//创建一个构造函数
function Person() {
this.sayHello = function() {
console.log('Hello,I am one Dog')
}
}
//创建两个对象
var dog1 = new Person(),
dog2 = new Person();
//两个实例对象进行比较
dog1.sayHello();
dog2.sayHello();
console.log("dog1.sayHello === dog2.sayHello的结果是:" + (dog1.sayHello === dog2.sayHello));
控制台输出结果:
这里dog1,dog2都是构造函数Person的实例,但是两个人的sayHello方法并不完全相等。也就是说dog1和dog2分别在自己所属空间开辟了一块内存。
夭寿啦!单身狗为何不报团取暖,不是说好一起相亲相爱吗!不是说好一起共享种子,一起开黑吗?月黑风高秋名山一起开车吗!
所以为了避免原本每天遭受狗粮侵蚀单身汪继续团结一致,这个时候原型prototype就起到很好的稳定dog群内团结的作用。
//创建一个构造函数
function Person(){};
Person.prototype.sayHello = function(){
console.log("Hello, I am one Dog")
}
//创建两个对象
var dog1 = new Person(),
dog2 = new Person();
//两个实例对象进行比较
dog1.sayHello();
dog2.sayHello();
console.log("dog1.sayHello === dog2.sayHello的结果是:"+ (dog1.sayHello === dog2.sayHello));
控制台输出结果:
说明此时两名单身狗又团结一致,资源共享sayHello方法。而不是每个私自建立一个空间,去存放sayHello方法。
当实例对象需要寻找sayHello方法的时候,就会先去构造函数Person函数当中寻找sayHello方法,然后Person函数方法当中没有找到,就会去Person的原型当中去找sayHello方法。(同理在JavaScript当中,如果创建多个对象,但是却只共享一个方法。减少了内存的使用,能够优化性能不少。)
而jQuery里面也充斥不少原型prototype,所以看下面jQuery代码,就会知道相应查找顺序了,同样也能更好的理解后面的代码。
jQuery无new构造
之前第一章,我们有讲过jquery通过如下代码来暴露接口:
window.jquery = window.$ = jQuery
举个栗子:
$("#box") = jQuery("#box")
那么jQuery这个函数开始执行,此时让我们打开jQuery源码,看看jQuery内部是如何实现的。
(function(window, undefined) {
var
// ...
jQuery = function(selector, context) {
return new jQuery.fn.init(selector, context, rootjQuery);
},
jQuery.fn = jQuery.prototype = {
init: function(selector, context, rootjQuery) {
// ...
}
}
jQuery.fn.init.prototype = jQuery.fn;
})(window);
估计有童鞋 jQuery.fn.init.prototype = jQuery.fn 这一句都会被卡主,满脸黑人问号。但是这句真的算是 jQuery 的绝妙之处。理解这几句很重要,分别解析一下:
(来自灵魂抽象派画师-车大棒)
1、首先要明确,使用
$(‘xxx’)
这种实例化方式,其内部调用的是return new jQuery.fn.init(selector, context, rootjQuery)
这一句话,也就是构造实例是交给了jQuery.fn.init()
方法取完成。
2、将
jQuery.fn.init
的 prototype 属性设置为jQuery.fn
,那么使用new jQuery.fn.init()
生成的对象的原型对象就是jQuery.fn
,所以挂载到jQuery.fn
上面的函数就相当于挂载到jQuery.fn.init()
生成的 jQuery 对象上,所有使用new jQuery.fn.init()
生成的对象也能够访问到jQuery.fn
上的所有原型方法。
3、也就是实例化方法存在这么一个关系链
jQuery.fn.init.prototype = jQuery.fn = jQuery.prototype ;
new jQuery.fn.init()
相当于new jQuery()
;
jQuery()
返回的是new jQuery.fn.init()
,而var obj = new jQuery()
,所以这 2 者是相当的,所以我们可以无 new 实例化 jQuery 对象。
-------来自某博客大牛的小结(看到好多博客上面都有,不清楚谁才是原创)
PS:
原本这里打算把晒上我用思维箭头图画出个整个结构之后,就基本上一句话可以带过了。但是我看到别人博客上这一段总结很好,所以就直接引用了。当然写博客的时候,我就料到直接引用可能会有点影响不好。修改一下,然后用自己语言来说,可能会效果好的多。
但是完全觉得没有必要, 好东西我觉得就应该直接拿出来分享。事实上我本来的学习jQuery源码就是吸收各种视频资源,以及各路大牛博客去学习参考。别人写的好,写的详细这就是无可厚非的。(如果有原话博客主,对我私自引用有意见。留言,我立刻删或者改。)
jQuery的链式调用
早在第一次接触jQuery的时候,就被它风骚的链式调用给吸引了,感觉操作真TMD的6到飞起。
例如:$('div').eq(0).show().end().eq(1).hide();
所以希望待会简单的谈及这个知识点之后,我不希望你们来一句:“大神,这波操作666!!”,而是高呼道:“what?这么简单!”(PS:大牛们请无视这句话,还有不懂这两句话差别的也请无视这句话!)
var oneDog = {
food : function(){
console.log("今天晚餐是泡面和一个卤鸡蛋!");
return this;
},
sad : function(){
console.log("坐地铁被喂了十几站的狗粮!");
return this;
},
game : function(){
console.log("今天DOTA2开黑10连跪");
return this;
},
}
oneDog.food().sad().game(); //没错,这样就是实现了链式调用。
然后控制台就能够依次输出每个方法当中的log语句,就是这么简单每次调用返回它自己本身就可以形成一个链式调用。(来!开始喊那句话吧!)
看过前面的小demo之后,让我们回过头来看jQuery的源码是如何实现链式调用。
首先第一步,显示HTML骨架部分:
<div>我是dog1</div>
<div>我是dog2</div>
接下来就是jQuery代码
console.log($(''div').eq(0))
这个时候控制台输出结果:
之后在eq(0)
后面紧紧跟end()
结束的时候,然后相当于整个代码返回给prevObject这个集合了:
//jQuery源码当中的end函数
end: function() {
return this.prevObject || this.constructor(null);
}
总的来说,
1、eq(i)
之后留下prevObject 属性,这个属性记录了操作的 jQuery 对象集合;
2、当我们在链式调用 end()
方法后,内部就返回当前 jQuery 对象的 prevObject 属性,完成回溯。
3、和前面我们返回的this的小demo,有异曲同工之妙。
小结:
今天将的知识点比较少,先是带大家回顾了prototype知识点,之后浅谈了一下jQuery的无new的构造结构,以及链式调用的原理。
两篇博客所讲的知识完全没有一些知名大牛博客一篇博客讲的知识点多,但是哪怕能讲懂一个点我也会很欣慰。有句话说的好:
不积跬步,无以至千里;不积小流,无以成江海。
原创文章,文笔有限,才疏学浅,文中若有不正之处,再次再次再次欢迎各位啪啪啪的打脸赐教。(有句话说的好,重要的词得说三遍。)
我是车大棒,我的目标是星辰与大海!
车大棒浅谈jQuery源码(二)的更多相关文章
- 车大棒浅谈jQuery源码(一)
背景 因为最近辞职找工作,投了许多家公司.结果简历要么石沉大海,一点音讯都没有,要么就是邮件回复说不匹配.后面加了一些QQ群,才发现原来我工作经验年限太少了.现在深圳都是3经验起步,北京据说更加恐怖. ...
- 浅谈flask源码之请求过程
更新时间:2018年07月26日 09:51:36 作者:Dear. 我要评论 这篇文章主要介绍了浅谈flask源码之请求过程,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随 ...
- 浅谈C++源码的过国内杀软的免杀
以下只是简单的思路和定位.也许有人秒过,但是不要笑话我写的笨方法.定位永远是过期不了的. 其实这里废话一下 , 本人并不是大牛 ,今天跟大家分享下 .所以写出这篇文章.(大牛飘过) 只是个人实战的经验 ...
- 浅谈 jQuery 事件源码定位问题
该方法已过期,chrome 48还是49开始,自带各种流行框架的事件绑定解析. 勾上这个选项即可. 昨天群里有人问了个事件源码定位的问题,简单描述下是这样的. 在一个不是自己写的页面上,如何快速定位到 ...
- 车大棒浅谈for循环+canvas实现黑客帝国矩形阵
背景: 一日在网上闲逛的之时,突然看到一个利用JQ插件实现canvas实现的电影黑客帝国的小Demo.觉得创意不错,就下载下来研究一下. 网上浏览jQuery的写法 $(document).ready ...
- jQuery源码二之extend的实现
extend是jQuery中一个比较核心的代码,如果有查看jQuery的源码的话,就会发现jQuery在多处调用了extend方法. 作用 对任意对象进行扩展 扩展某个实例对象 对jquery本身的实 ...
- 一个QQ木马的逆向分析浅谈(附带源码)
程序流程:首先注册自己程序的窗口以及类等一系列窗口操作,安装了一个定时器,间隔为100ms,功能搜索QQ的类名,如果找到就利用FindWindow("5B3838F5-0C81-46D9-A ...
- jQuery源码解析资源便签
最近开始解读jQuery源码,下面的链接都是搜过来的,当然妙味课堂 有相关的一系列视频,长达100多期,就像一只蜗牛慢慢爬, 至少品读三个框架,以后可以打打怪,自己造造轮子. 完全理解jQuery源代 ...
- Jquery源码中的Javascript基础知识(二)
接上一篇,jquery源码的这种写法叫做匿名函数自执行 (function( window, undefined ) { // code })( window ); 函数定义了两个参数window和u ...
随机推荐
- java多线程安全问题-同步修饰符于函数
上一篇文章通过卖票使用同步代码块的方法解决安全问题本篇文章首先探讨如何找出这样的安全问题,并提出第二种方式(非静态函数synchronized修饰)解决安全问题 /* 需求: 银行有一个公共账号金库 ...
- LAMP学习小记
记录今天学习到的解决LAMP环境搭建的两个小问题: 问题1.xshell无法连接到虚拟机上的linux主机 解决方法: (1)进入网络配置文件: vi /etc/sysconfig/network-s ...
- 【转】IntelliJ IDEA2016.1 + maven 创建java web 项目
最近开始使用idea 来写java项目了,这个很流行,相比Eclipse方便了很多.功能多了,相对应的使用的复杂度也较高了,因为网上很多的使用和创建项目的简单教程,都是基于老版本的,每个新版本都有不一 ...
- 探索Javascript设计模式---单例模式
最近打算系统的学习javascript设计模式,以便自己在开发中遇到问题可以按照设计模式提供的思路进行封装,这样可以提高开发效率并且可以预先规避很多未知的问题. 先从最基本的单例模式开始. 什么是单例 ...
- URLencode 特殊字符 转义 遇上的坑
在项目中遇到一个问题,在webveiw和原生之间进行传值的时候,出现了一些encode的小问题.看起来很简单的问题,实际上却存在不小的坑. 首先说一下目前项目的结构,在一个activity中,webv ...
- js五种设计模式说明与示例
第一种模式:js工厂模式 var lev=function(){ return "啊打"; }; function Parent(){ ...
- Unity3d中如何混用三种脚本语言?
首先要明白,这三种说的混用是指文件级别的混用,就是说一个文件是由一种语言写的.而不是说你这一个文件可以混用这三种语言,注意这是不允许的. 第二要明白,在unity3d中为什么可以使用三种语言混合开发? ...
- BI数据分析中KPI,KGI,CSF概念
1. 行为产生数据 先来谈一谈,自己对数据基础概念的思考.我认为首先要建立的核心观点是:行为产生数据. 翻译一下这个核心观点.意思就是,当我们在思考或描述数据相关需求的时候,必然要包含这样的语素:&q ...
- Protobuf学习 - 入门
古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 -- 苏轼·<晁错论> 从公司的项目源码中看到了这个东西,觉得挺好用的,写篇博客做下小总结.下面的操作以C++为编程语言,protoc的版 ...
- 自己动手编写Maven的插件
Maven的插件机制是完全依赖Maven的生命周期的,因此理解生命周期至关重要.本文参考官方文档后使用archetype创建,手动创建太麻烦. 创建创建项目 选择maven-archetype-moj ...