菜鸟的jQuery源码学习笔记(二)
jQuery对象是使用构造函数和原型模式相结合的方式创建的。现在来看看jQuery的原型对象jQuery.prototype:
jQuery.fn = jQuery.prototype = {
//成员变量和方法
}
这里给原型对象起了一个别名叫做jQuery.fn。要注意的是这个jQuery.fn可不是jQuery对象的属性,而是jQuery构造方法本身的属性,它是不会传给它所创建的对象的。如果你在控制台敲$().fn的话输出的结果会是undefined。接下来看看原型对象里面有些什么:
jquery: "2.1.1", constructor: jQuery,
jquery:在原型对象中,先定义了jquery属性来标识版本信息,这里是2.1.1版。在我们写代码的时候可以通过查看这个属性判断对象是不是jQuery对象。
constructor:这个属性在低版本的jQuery代码中是没有的(例如远古的1.2.6版本)。在这里我能看见这个属性我真的觉得现在的jQuery成熟了。每一个对象都有一个constructor属性,是由创建它的构造函数的原型对象传递而来,指向了创建它的构造方法。也就是如果你在chrome的控制台敲:
var obj = {}; obj.constructor;
控制台会显示:
function Object() { [native code] }
构造函数的原型是在定义构造函数的时候自动生成,其中的constructor会自动指向该构造函数。也就是你在输入:
function Obj(){} Obj.prototype.constructor
控制台会输出:
function Obj(){}
现在回过头我们再来看看jQuery的代码。定义jQuery.prototype时:
jQuery.fn = jQuery.prototype = {
//成员变量和方法
}
这里的过程其实是新建一个对象,然后将jQuery.prototype指向这个新建的对象。而这时新建对象因为是由function Object(){}方法构建的。所以它的constructor属性其实是指向的function Object(){}方法。进而导致所有由jQuery方法创建的对象的constructor也是指向的
function Object(){}方法。这里重新定义jQuery.prototype.constructor属性,让它重新指向jQuery构造函数。平常我们在使用jQuery的时候也许永远也不会用到constructor这个属性,但是这种小细节的完善无疑让整个代码变得严谨很多。
继续往下看代码:
// Start with an empty selector
selector: "", // The default length of a jQuery object is 0
length: 0,
selector:这个属性指的是默认的选择器。
length:jQuery对象其实是一个类数组对象。什么叫类数组对象?我的理解是它不是一个数组,而是一个对象但是当我们访问它的数据时某些表现形式跟数组很相似,比如可以用[0]、[1]....[n]来访问数据,可以用length来获取数据的数目。jQuery就是一种类数组对象通过选择器选择页面dom元素,并以jq[0]、jq[1]、jq[2]...、jq[n]的形式将个元素存储在jQuery对象中,这个length属性就是用来记录元素个数。
继续往下:
var arr = []; var slice = arr.slice; toArray: function() {
return slice.call(this);
},
toArray:这个方法是将jQuery对象转化为一个数组(是真正的数组哦)。我们知道数组的
slice(start,end)
方法可从已有的数组中返回选定的元素而不破坏原有的数组,当参数不填的时候就返回这个数组的一个副本。因为jQuery对象是类数组对象,所以这里直接将数组arr中slice的对象上下文换成当前jQuery对象(不知道这个对象上下文能不能理解成作用域哈,不过this肯定是指的新对象啦)。slice函数执行后返回一个真正的js数组,里面的元素就是jQuery对象中的各个dom元素,但是又不破坏原来的jQuery对象,这一招真的挺不错,一行代码使用现有的资源解决了很多事情,这种思路要多学习。不过slice的调用我们还可以用
Array.prototype.slice.call(this)
这种方式调用也是可以的,不用特意新建一个对象。
往下:
get: function(num) {
return num != null ? // Return just the one element from the set
(num < 0 ? this[num + this.length] : this[num]) : // Return all the elements in a clean array
slice.call(this);
},
get:这个方法感觉根据传参不同会有两个功能。一个是如果传参num不为空的话,那么根据num返回jQuery对象中的相应dom元素。另一个就是当num为空得时候将jQuery对象转换为数组。所以我一直很奇怪为啥有了get方法还要专门写一个toArray方法,希望有大大为我解惑。
咱们继续:
pushStack: function(elems) { // Build a new jQuery matched element set
//jQuery.merge:合并两个数组的内容到第一个数组中
var ret = jQuery.merge(this.constructor(), elems); // Add the old object onto the stack (as a reference)
ret.prevObject = this;
ret.context = this.context; // Return the newly-formed element set
return ret;
},
pushStack:大家都知道当我们使用jQuery选择区创建jQuery对象后,例如$(".class"),还可以使用jq.find、jq.filter等方法进一步处理,返回新的jQuery对象。但是这样往往会对旧的jQuery产生“破坏”性德影响,因为它们会修改匹配元素的集合(在jQuery中被称为matched element set)所以jQuery在进行这种“破坏性”的操作之前就会调用pushStack方法将现有的匹配元素集合暂时保存起来。
首先调用jQuery.merge方法,它将两个数组合并到第一个数组中。不过我觉得很有意思的是两个传参:
第一个参数this.constructor指的是jQuery构造方法原型对象中的constructor属性,这个前面说过。的this.constructor()指的是调用jQuery构造方法构建一个新对象,如同$()一样。因为jQuery是类数组对象所以也可以充当merge的传参。我觉得很炫酷的是这里创建新jQuery的写法,要是我本人的话我肯定会直接用jQuery()这么写了。
第二个参数elems就是pushStack传进来的参数了,它可以是真正的数组,也可以是类数组对象。通过merge方法,可以将elems转化为一个jQuery对象。
接下来就很简单了,将当前对象用ret.prevObject保存起来,值得一提的是这里还专门用了一个ret.context来保存当前jQuery对象的选择器上下文,就是使用选择器匹配元素时第二个参数,eg:$("div",document.getElementById("id"))。我查了一下w3c.school,context 属性在 jQuery version 1.10 中被弃用,但是高版本的jQuery中还能看到这个,所以我也不知道到底怎么回事。
不过既然说到jQuery.merge了那干脆来看看它吧:
merge: function(first, second) {
var len = +second.length,
j = 0,
i = first.length; for (; j < len; j++) {
first[i++] = second[j];
} first.length = i; return first;
},
具体代码就不细说了~~~没什么技术含量,值得一提的是从merge的代码上看好像并没有去重的功能。这里的去重不仅仅是重复数字什么的,更包含重复的元素。比方说:
var arr1 = [], arr2 = []; var ele = document.getElementById("id"); arr1.push(ele);
arr2.push(ele); var arr3 = jQuery.merge(arr1, arr2);
运行后arr3.length将会是2虽然两个元素其实是同一个dom对象的引用。
菜鸟的jQuery源码学习笔记(二)的更多相关文章
- 菜鸟的jQuery源码学习笔记(前言)
前言 相信任何一名前端开发人员或者是前端爱好者都对jQuery不陌生.jQuery简单易用,功能强大,特别是拥有良好的浏览器兼容性,大大降低了前端开发的难度,使得前端开发变得“平易近人起来”.自从本人 ...
- jquery源码学习笔记二:jQuery工厂
笔记一里记录,jQuery的总体结构如下: (function( global, factory ) { //调用factory(工厂)生成jQuery实例 factory( global ); }( ...
- jQuery源码学习笔记二
//添加实例属性和方法 jQuery.fn = jQuery.prototype = { // 版本,使用方式:$().jquery弹出当前引入的jquery的版本 jquery: core_vers ...
- 菜鸟的jQuery源码学习笔记(一)
整个jQuery是一个自调用的匿名函数: (function(global, factory) { if (typeof module === "object" && ...
- 菜鸟的jQuery源码学习笔记(三)
each: function(callback, args) { return jQuery.each(this, callback, args); }, each:这个调用了jQuery.each方 ...
- jquery源码学习笔记三:jQuery工厂剖析
jquery源码学习笔记二:jQuery工厂 jquery源码学习笔记一:总体结构 上两篇说过,query的核心是一个jQuery工厂.其代码如下 function( window, noGlobal ...
- jQuery源码学习笔记一
学习jQuery源码,我主要是通过妙味视频上学习的.这里将所有的源码分析,还有一些自己弄懂过程中的方法及示例整理出来,供大家参考. 我用的jquery v2.0.3版本. var rootjQuery ...
- jquery源码学习笔记(一)jQuery的无new构建
本人是一名.net程序员..... 你一个.net coder 看什么jQuery 源码啊? 原因吗,很简单.技多不压身吗(麻蛋,前端工作好高...羡慕). 我一直都很喜欢JavaScript,废话不 ...
- jquery源码学习笔记一:总体结构
练武不练功,到老一场空.计算机也一样. 计算机的功,就是原理.如果程序员只会使用各种函数,各种框架,而不知其原理,顶多熟练工人而已.知其然,更要知其所以然. jquery我们用得很爽,但它究竟咋实现的 ...
随机推荐
- codeforces 339C Xenia and Bit Operations(线段树水题)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud Xenia and Bit Operations Xenia the beginn ...
- UVA11401Triangle Counting(简单计数)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud 题目意思:从1,2,3,……,n中选出3个不同的整数使其构成一个三角形,有多少种方 ...
- PHP PSR-2 代码风格规范 (中文版)
代码风格规范 本篇规范是 PSR-1 基本代码规范的继承与扩展. 本规范希望通过制定一系列规范化PHP代码的规则,以减少在浏览不同作者的代码时,因代码风格的不同而造成不便. 当多名程序员在多个项目中合 ...
- NodeJS和C++的性能比较(转)
原文地址: http://www.web-tinker.com/article/20374.html 前段时间做了个实验,测试了1E9次的空循环在NodeJS和C++中的执行用时.于是我和小伙伴们瞬间 ...
- 查文件大小列表 MySQL问题
du -sh /* | sort -nr 打开网站发现Too many connections The server quit without updating PID file (/usr/loca ...
- 典型的DIV CSS三行二列居中高度自适应布局
如何使整个页面内容居中,如何使高度适应内容自动伸缩.这是学习CSS布局最常见的问题.下面就给出一个实际的例子,并详细解释.(本文的经验和是蓝色理想论坛xpoint.guoshuang共同讨论得出的.) ...
- linux开启mysql远程登录
Mysql默认root用户只能本地访问,不能远程连接管理mysql数据库,Linux如何开启mysql远程连接?设置步骤如下:1.GRANT命令创建远程连接mysql授权用户itloggermysql ...
- 2015第10周五CSS—2
经常遇到的浏览器兼容性有哪些?如何解决? 1.浏览器默认的margin和padding不同.解决方案是加一个全局的*{margin:0;padding:0;}来统一. 2.IE6双边距bug:块属性标 ...
- Red and Black(BFS or DFS) 分类: dfs bfs 2015-07-05 22:52 2人阅读 评论(0) 收藏
Description There is a rectangular room, covered with square tiles. Each tile is colored either red ...
- MySQL Workbench导出数据库
步骤: 1. 打开mysql workbench,进入需要导出的数据库,点击左侧栏的[Management]tab键. 2. 点选要输出的数据库 点击[Data Export] 选在要输出的数据库 选 ...