虽然被人嘲笑过在简历里写自己用过jQuery,但我觉得jQuery并不是一个很low的东西,它作为一个库有很多值得学习的地方。在面试的时候,还被问到相关的问题,如选择器实现,链式调用,事件委托,deffered对象实现等,答得不是很好。我决定抽点时间看看这块内容,顺便给久未更新的博客新增一些内容。
看的源码来自:https://github.com/jquery/jquery
jQuery的组成架构 (待整理)
jquery.js 采用AMD的写法,core 就对应 jQuery
- 看下core.js的代码组织12345678910111213141516171819202122232425262728// core.jsdefine( ["./var/arr","./var/document",// ...], function( arr, document) {"use strict";// 无 new 的构造方式var jQuery = function( selector, context ) {return new jQuery.fn.init( selector, context );},// 在原型链上加各种方法, fn更简洁jQuery.fn = jQuery.prototype = {};jQuery.extend = jQuery.fn.extend = function() {};jQuery.extend( {} );return jQuery;} );
无new的构造方式
无new的实现很好理解,管它调用的时候带不带new,jQuery都new一个实例出来,返回。
问题:
Q: 可以直接写new jQuery()吗?
A: 会无限调用自己,所以需要一个别的构造器init
Q: 构造器返回的实例应该具备所有jQuery的方法,怎么实现?
A: 可以通过原型实现,而且这样做实例的__proto__属性正好就直接为jQuery的原型
Q: 为什么init要加在jQuery的原型上?
A: 不知道?
|
|
扩展方法extend
jQuery.extend( [deep ], target, object1 [, objectN ] )
默认为浅拷贝,拷贝时舍弃undefined的属性
深拷贝时,对object和数组进行递归处理
extend写好了,给jQuery或是它的原型扩展方法就方便多了:)
Q: 中间调用的isPlainObject是什么?
A: 检查一个元素是不是通过{}或者new Object生成,对于其他复杂的对象(document, dom等),原型不知道如何处理,extend的时候就直接引用复杂对象了
Q: 那如何检测一个对象是这样的普通对象?
A: 利用toString看它的构造函数是否是Object
注意: Object.create(null) 返回的对象,为{},是什么属性都没有的空对象,而且什么都不继承,直接没有__proto__属性。
Q: core.js里还有一个检测是不是类数组对象的方法,是不是只要检测length属性就可以了?
A: function和window也有length属性,
function的length是形参的个数, window的length 属性返回在当前窗口中frames的数量
|
|
这个(length-1) 觉得并没有什么用,都能构造出假的“数组”
core.js 给jquery扩展了不少方法,这里我先不看,等用到再说。