JQuery源码分析(八)

网友投稿 276 2022-09-05

JQuery源码分析(八)

jQuery的each迭代器

jQuery的each方法从使用上就要分2种情况:

$.each()函数$(selector).each()

$.each()函数和$(selector).each()是不一样的,后者是专门用来遍历一个jQuery对象的,是为jQuery内部服务的。

$.each()函数可用于迭代任何集合,无论是“名/值”对象(JavaScript对象)或数组。在迭代数组的情况下,回调函数每次传递一个数组索引和相应的数组值作为参数。

(该值也可以通过访问this关键字得到,但是JavaScript始终将this值作为一个Object,即使它是一个简单的字符串或数字值。)该方法返回其第一个参数,这是迭代的对象。

jQuery的实例方法最终也是调用的静态方法。

其中each的实例方法如下:

可见内部是直接调用的静态方法:

each: function(callback, args) { return jQuery.each(this, callback, args);},

jQuery.each静态方法:

each: function(obj, callback, args) { var value, i = 0, length = obj.length, isArray = isArraylike(obj); if (args) { if (isArray) { for (; i < length; i++) { value = callback.apply(obj[i], args); if (value === false) { break; } } } else { for (i in obj) { value = callback.apply(obj[i], args); if (value === false) { break; } } }

实现原理几乎一致,只是增加了对于参数的判断。对象用for in遍历,数组用for遍历。

jQuery可以是多个合集数组DOM,所以在处理的时候经常就针对每一个DOM都要单独处理,所以一般都需要调用this.each 方法,如下代码:

dequeue: function( type ) { return this.each(function() { jQuery.dequeue( this, type ); }); },

迭代器除了单纯的遍历,在jQuery内部的运用最多的就是接口的抽象合并,相同功能的代码功能合并处理:

例如一:

jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { class2type[ "[object " + name + "]" ] = name.toLowerCase();});

例如二:

jQuery.each({ mouseenter: "mouseover", mouseleave: "mouseout", pointerenter: "pointerover", pointerleave: "pointerout"}, function( orig, fix ) { //处理的代码});

可以看出上面代码方法,针对相同的功能,节约了大量的代码空间。

实例代码:

理解观察者模式

jQuery回调对象之前,我们有必要先理解其背后的设计思想 - “观察者模式”。

观察者模式 (pub/sub) 的背后,总的想法是在应用程序中增强松耦合性。并非是在其它对象的方法上的单个对象调用。一个对象作为特定任务或是另一对象的活动的观察者,并且在这个任务或活动发生时,通知观察者。观察者也被叫作订阅者(Subscriber),它指向被观察的对象,既被观察者(Publisher 或 subject)。当事件发生时,被观察者(Publisher)就会通知观察者(subscriber)。

观察者的使用场合就是:当一个对象的改变需要同时改变其它对象,并且它不知道具体有多少对象需要改变的时候,就应该考虑使用观察者模式。先看官网的demo这个例子,涉及到了 add 与 fire方法

是基于发布订阅(Publish/Subscribe)的观察者模式的设计。

作为 $.Callbacks() 的创建组件的一个演示,只使用回调函数列表,就可以实现 Pub/Sub 系统,将 $.Callbacks 作为一个队列。

我们来模拟常规下最简单的实现:

JS里对观察者模式的实现是通过回调来实现的,我们来先定义一个Observable对象,其内部包含了2个方法:订阅add方法与发布fire方法,如下代码:

var Observable = { callbacks: [], add: function(fn) { this.callbacks.push(fn); }, fire: function() { this.callbacks.forEach(function(fn) { fn(); }) }}

使用add开始订阅:

Observable.add(function() { alert(1)})Observable.add(function() { alert(2)})

使用fire开始发布:

Observable.fire(); // 1, 2

设计的原理:

开始构建一个存放回调的数组,如​​this.callbacks= [] ​​添加回调时,将回调push进this.callbacks,执行则遍历this.callbacks执行回调,也弹出1跟2了。当然这只是简洁的设计,便于理解,整体来说设计的思路代码都是挺简单的,那么我们从简单的设计深度挖掘下这种模式的优势。

注意:如果没有做过复杂交互设计,或者大型应用的开发者,可能一开始无法理解这模式的好处,就简单的设计而言用模式来处理问题,有点把简单的问题复杂化。我们不是为了使用模式而使用的。

组件开发为了保证组件可以在不同的项目中都适用,其必须是对其常用功能抽象出来加以实现,绝不会包含具体的业务逻辑而某一特定的项目使用者在其业务场景中使用组件时不可避免的要加入不同场景的业务逻辑。

实例代码 :

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:JQuery源码解析(十)
下一篇:餐厅如何零成本做营销?这10个实用招数请收好!
相关文章

 发表评论

暂时没有评论,来抢沙发吧~