Jquery的$(selector).each()和$.each()原理和区别
我们都用过Jqurey中的each函数,都知道each()有两种方式去调用,一种是通过$.each()调用,另一种是$(selector).each()去调用,那么它们之间有什么区别?
翻看一下Jquery源码就会知道,$.each()是核心的实现,$(selector).each()是调用的$.each(),先来分析一下$.each()的源码(在底部):
each(obj,callback,args)函数接收3个参数:obj--要遍历的对象或数组、callback--要遍历执行的回调函数、args--自己指定的数组(先无视)。
1.没有args的情况
一般来说,args是不常用的,所以先不讨论当if(args)成立的情况,也就是直接看在代码中标为灰色的部分,这也是each()函数核心的部分
if(isArray) {
for(; i < length; i++) {
value = callback.call(obj[i], i, obj[i]);
if(value === false) { break; }
}
}
如果你要遍历的对象,是数组类型,则进入此代码块
for循环遍历数组的每个元素,然后利用call方法,执行obj[i].callback(i,obj[i]),
所以,自己再写回调函数的时候,应该意识到jquery会用数组的每个对象去执行你的回调函数,参数传的是元素在数组中index和该元素,同时回调方法内部的this,也指向该元素;
下一行是判断回调函数是否返回了值,如果回调函数返回false,则跳出该数组的循环。
如果自己传的对象也是可以遍历的,代码和上面数组遍历也是一样的
else {
for(i in obj) {
value = callback.call(obj[i], i, obj[i]);
if(value === false) { break; }
}
}
如果自己传的是对象,则用for(x in y)遍历对象的属性,
原理和上面一样,只不过换成对象内部的属性x,去执行回调函数,相当于obj.attr.callback(i,obj.attr);
回掉函数中如果返回false,也是会结束循环操作。
2.有args的情况
当调用each()有第三个参数的时候,便会进入下面的代码块,来分析下:
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; }
}
}
同样道理,会先判断你要遍历的对象是否是数组,如果是数组,则遍历数组的元素obj[i],并执行obj[i].callback(args)
注意!这个地方传的参数是你自己传进来的args数组,这是和没有args参数不一样的地方,也就是说如果你调用each函数是传入了自己的数组参数,回调函数的参数列表就是你所传的args数组。
其他的同上。
还有大家注意到了没有?有args和没有args的区别就是一个用了apply(),而另一个用了call(),这儿简单记一下他俩的区别: Apply():While the syntax of this function is almost identical to that of call(), the fundamental difference is that call() accepts anargument list,while apply() accepts a single array of arguments. --引自MDN 翻译一下就是:虽然这个apply()和call()句法几乎一致,但是有一个重要的区别就是call()函数是接受多个参数,而apply()仅仅接受一个数组对象。
$(selector).each(callback,args)函数接收2个参数:callback--要遍历执行的回调函数、args--自己指定的数组。
明白了$.each()函数,$(selector).each就简单了,翻开源码,$(selector).each内部就是调用的$.each()函数,源码如下:
each: function( callback, args ) {
return jQuery.each( this, callback, args );
},
可以看到,在调用$.each()的时候,obj参数是写成了this,也就是$(selector),这是jquery选择器返回一个jquery内部对象。
总结:$.each()和$(selector).each()的区别就是前者可以针对所有对象或者数组进行遍历,而后者是针对jquery选择器返回的jquery内部对象进行遍历,前者更强大一些
附上源码
//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; }
}
}
// A special, fast, case for the most common use of each
} else {
if(isArray) {
for(; i < length; i++) {
value = callback.call(obj[i], i, obj[i]);
if(value === false) { break; }
}
} else {
for(i in obj) {
value = callback.call(obj[i], i, obj[i]);
if(value === false) { break; }
}
}
}
Jquery的$(selector).each()和$.each()原理和区别的更多相关文章
- 细说jQuery原型的创建和实现原理,并用实例简单模仿
在解析jQuery实现机理之前,我们先总结一下几点知识,这些都是我学习路上遇到的坑,我跌倒过很多次,现在把它补上: 1)自定义构造函数,如下例: function person(){ this.nam ...
- jQuery插件实现的方法和原理简单说明
下文来自 http://www.itzhai.com/jquery-plug-ins-to-achieve-the-methods-and-principles-of-simple-instructi ...
- jquery源码中noConflict(防止$和jQuery的命名冲突)的实现原理
jquery源码中noConflict(防止$和jQuery的命名冲突)的实现原理 最近在看jquery源码分析的视频教学,希望将视频中学到的知识用博客记录下来,更希望对有同样对jquery源码有困惑 ...
- jquery的bind跟on绑定事件的区别
jquery的bind跟on绑定事件的区别:主要是事件冒泡: jquery文档中bind和on函数绑定事件的用法: .bind(events [,eventData], handler) .on(ev ...
- jquery中,size()和length()方法有啥区别
jquery中,size()和length()方法有啥区别? size()是jQuery提供的函数,而length是属性(不带括号). jQuery提供的源代码是这样的: size: function ...
- jquery的hover mouseover mouseout mouseenter mouseleave的区别
jquery的hover mouseover mouseout mouseenter mouseleave的区别 1.mouseover mouseout mouseover - 鼠标指针经过任何子元 ...
- 前端笔记之jQuery(上)加载函数的区别&对象&操作HTML/CSS&动画&选择器
一.jQuery简介 1.0 JavaScript编程比较恶心的地方 恶心1:选择元素麻烦,全线兼容的方法只有getElementById()和getElementsByTagName()两个.其他的 ...
- HashMap,Hashtable,ConcurrentHashMap 和 synchronized Map 的原理和区别
HashMap 是否是线程安全的,如何在线程安全的前提下使用 HashMap,其实也就是HashMap,Hashtable,ConcurrentHashMap 和 synchronized Map 的 ...
- 转:jquery的$(function(){})和$(document).ready(function(){}) 的区别
原文链接:https://www.cnblogs.com/slyzly/articles/7809935.html [转载]jquery的$(function(){})和$(document).rea ...
随机推荐
- Swift_提醒框
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px Menlo; color: #ffffff } p.p2 { margin: 0.0px 0. ...
- 使用ab对nginx进行压力测试
nginx以高并发,省内存著称. 相信大多数安装nginx的同学都想知道自己的nginx性能如何. 我想跟大家分享下我使用ab工具的压力测试方法和结果, ab是针对apache的性能测试工具,可以只安 ...
- C++类成员在内存中的存储及对齐方式
前言:数据对齐的基本理论参见文章:http://www.cnblogs.com/MyBlog-Richard/articles/5993448.html 一.空类的大小 C++中空类的大小是1,这是因 ...
- Could not find or load main class org.gradle.wrapper.GradleWrapperMain解决办法
解决办法: gradlew is the gradle wrapper executable - batch script on windows and shell script elsewhere. ...
- QEMU VCPU热插特性
最近学习QEMU中VCPU热插特性,需要了解QEMU中VCPU热插的整个流程,VCPU热插是QEMU主板的一个feature. 1:这里先分析一下QEMU的主板模拟,主板在QEMU的设备模型中对应的是 ...
- c/c++ long long 和__64int区别
在C/C++中,64为整型一直是一种没有确定规范的数据类型.现今主流的编译器中,对64为整型的支持也是标准不一,形态各异.一般来说,64位整型的定义方式有long long和__int64两种(VC还 ...
- CentOs 6.5 安装Ganglia步骤
一 . 说明 Ganglia由gmond.gmetad和gweb三部分组成 gmond(Ganglia Monitoring Daemon)是一种轻量级服务,安装在每台需要收集指标数据的节点主机上.g ...
- python 解压 压缩包
转 http://m.blog.csdn.net/blog/wice110956/26597179# 这里讨论使用Python解压如下五种压缩文件: .gz .tar .tgz .zip .rar ...
- ASP.NET运作流程
当我们在浏览器输入域名访问服务器资源时,会向服务器发送Http请求,并经由IIS处理后,交由ASP.NET托管程序处理,进入ASP.NET管道.在IIS内部如何处理我们不需要深入去了解,在ASP.NE ...
- Ubuntu14.04安装配置web/ftp/tftp/dns服务器
目录: 1.安装ftp服务器vsftpd --基于tcp,需要帐号密码 2.安装tftp服务器tftpd-hpa,tftp-hpa --udp 3.web服务器--使用Apache2+Mysql+PH ...