jquery原型方法map的使用和源码分析
原型方法map跟each类似调用的是同名静态方法,只不过返回来的数据必须经过另一个原型方法pushStack方法处理之后才返回,源码如下:
map: function( callback ) {
return this.pushStack( jQuery.map(this, function( elem, i ) {
return callback.call( elem, i, elem );
}));
},
本文主要就是分析静态map方法至于pushStack在下一篇随笔里面分析;
首先了解下map的使用(手册内容)
$.map将一个数组中的元素转换到另一个数组中。
作为参数的转换函数会为每个数组元素调用,而且会给这个转换函数传递一个表示被转换的元素作为参数。
转换函数可以返回转换后的值、null(删除数组中的项目)或一个包含值的数组,并扩展至原始数组中。
参数
arrayOrObject,callbackArray/Object,FunctionV1.6
arrayOrObject:数组或者对象。
为每个数组元素调用,而且会给这个转换函数传递一个表示被转换的元素作为参数。
函数可返回任何值。
另外,此函数可设置为一个字符串,当设置为字符串时,将视为“lambda-form”(缩写形式?),其中 a 代表数组元素。
如“a * a”代表“function(a){ return a * a; }”。
示例1:
//将原数组中每个元素加 4 转换为一个新数组。 //jQuery 代码: $.map( [0,1,2], function(n){
return n + 4;
});
//结果: [4, 5, 6]
示例2:
//原数组中大于 0 的元素加 1 ,否则删除。 //jQuery 代码: $.map( [0,1,2], function(n){
return n > 0 ? n + 1 : null;
});
//结果: [2, 3]
示例3:
//原数组中每个元素扩展为一个包含其本身和其值加 1 的数组,并转换为一个新数组 //jQuery 代码: $.map( [0,1,2], function(n){
return [ n, n + 1 ];
});
//结果: [0, 1, 1, 2, 2, 3]
可以看出map方法跟each方法类似通过循环每个对象或者数组的“项”执行回调函数来实现对数组或者对象的操作,但是这两个方法也有很多不同点
比如each()返回的是原来的数组,并不会新创建一个数组,而map则会创建新的数组,;each遍历是this指向当前数组或对象值,map则指向window,因为在源码中并不像each那样使用对象冒充;
例如:
var items = [1,2,3,4];
$.each(items, function() {
alert('this is ' + this);
});
var newItems = $.map(items, function(i) {
return i + 1;
});
// newItems is [2,3,4,5] //使用each时,改变的还是原来的items数组,而使用map时,不改变items,只是新建一个新的数组。 var items = [0,1,2,3,4,5,6,7,8,9];
var itemsLessThanEqualFive = $.map(items, function(i) {
// removes all items > 5
if (i > 5)
return null;
return i;
});
// itemsLessThanEqualFive = [0,1,2,3,4,5]
言归正传回到map源码
// arg is for internal usage only
map: function( elems, callback, arg ) {
var value, key, ret = [],
i = 0,
length = elems.length,
// jquery objects are treated as arrays
isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; // Go through the array, translating each of the items to their
if ( isArray ) {
for ( ; i < length; i++ ) {
value = callback( elems[ i ], i, arg ); if ( value != null ) {
ret[ ret.length ] = value;
}
} // Go through every key on the object,
} else {
for ( key in elems ) {
value = callback( elems[ key ], key, arg ); if ( value != null ) {
ret[ ret.length ] = value;
}
}
} // Flatten any nested arrays
return ret.concat.apply( [], ret );
},
首先还是声明几个变量为接下来的遍历做准备,其中jsArray变量用来简单区分对象和数组,这个布尔复合表达式比较长不过只要记住js运算符的有优先顺序就不难理解了,首先括号优先执行然后就是逻辑与》逻辑或》全等》赋值,然后就可以分析啦
首先圆括号里先计算然后结果加上 length !== undefined 、 typeof length === "number这两个必要条件最后的结果再跟elems instanceof jQuery进行逻辑或的运算,简单的说就是isArray为真的情况有:
1、elems instanceof jQuery 为true 换言之就是jquery对象
2、length !== undefined && typeof length === "number" 和 length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems )这三个至少成立一个
可以拆分为3个小情况
length是存在并且是数字而且待遍历的数组或者类数组等length属性大于0 length-1存在 这样就保证了是能遍历的,比如对于jquery对象 domList对象等
length是存在并且是数字而且length属性等于0 如果是0也没关系就是不会遍历
length是存在并且是数字而且待遍历对象是纯数组
满足这些条件之后开始根据isArray的结果分开遍历,对于“数组”采用for循环,对于对象采用for...in循环
// Go through the array, translating each of the items to their
if ( isArray ) {
for ( ; i < length; i++ ) {
value = callback( elems[ i ], i, arg ); if ( value != null ) {
ret[ ret.length ] = value;
}
}
是数组或者类数组的时候直接把循环的每一项的值和指针以及arg参数传入回调函数中执行,arg参数是此方法内部使用的参数,跟each以及一些其他jquery方法很相似,只要在执行回调函数时不返回null就把执行返回的结果添加到新数组中,对象操作亦是如此直接略过
// Flatten any nested arrays
return ret.concat.apply( [], ret );
最后将结果集扁平化,为什么有这一步呢?因为map是可以扩展数组的在前面第3个示例就是如此:
$.map( [0,1,2], function(n){
return [ n, n + 1 ];
});
如果是这样使用的话得到的新数组是一个二维数组,所以必须降维
ret.concat.apply( [], ret )等价于[].concat.apply([],ret)关键作用的是apply,因为apply的第二个参数把ret的数组分成多个参数传入给concat把二维数组转化为一维数组这个用法还是值得收藏的的
map方法简单分析完毕,能力有限错误之处望多多指正。
jquery原型方法map的使用和源码分析的更多相关文章
- jQuery原型属性constructor,selector,length,jquery和原型方法size,get,toArray源码分析
首先看一下在jQuery1.7.1中定义的原型属性和方法有哪些? init方法作为实际的构造函数已经详细分析过了,需要了解可以参考http://www.cnblogs.com/yy-hh/p/4492 ...
- jQuery静态方法inArray,grep,merge,makeArray方法使用和源码分析
inArray方法 确定第一个参数在数组中的位置,从0开始计数(如果没有找到则返回 -1 ). 示例: var arr = [ 4, "Pete", 8, "John&q ...
- Quartz学习--二 Hello Quartz! 和源码分析
Quartz学习--二 Hello Quartz! 和源码分析 三. Hello Quartz! 我会跟着 第一章 6.2 的图来 进行同步代码编写 简单入门示例: 创建一个新的java普通工程 ...
- jQuery 2.1.4版本的源码分析
jQuery 2.1.4版本的源码分析 jquery中获取元素的源码分析 jQuery.each({// 获取当前元素的父级元素 parent: function(elem) { var parent ...
- Android Debuggerd 简要介绍和源码分析(转载)
转载: http://dylangao.com/2014/05/16/android-debuggerd-%E7%AE%80%E8%A6%81%E4%BB%8B%E7%BB%8D%E5%92%8C%E ...
- Java并发编程(七)ConcurrentLinkedQueue的实现原理和源码分析
相关文章 Java并发编程(一)线程定义.状态和属性 Java并发编程(二)同步 Java并发编程(三)volatile域 Java并发编程(四)Java内存模型 Java并发编程(五)Concurr ...
- Kubernetes Job Controller 原理和源码分析(二)
概述程序入口Job controller 的创建Controller 对象NewController()podControlEventHandlerJob AddFunc DeleteFuncJob ...
- Kubernetes Job Controller 原理和源码分析(三)
概述Job controller 的启动processNextWorkItem()核心调谐逻辑入口 - syncJob()Pod 数量管理 - manageJob()小结 概述 源码版本:kubern ...
- Kubernetes Job Controller 原理和源码分析(一)
概述什么是 JobJob 入门示例Job 的 specPod Template并发问题其他属性 概述 Job 是主要的 Kubernetes 原生 Workload 资源之一,是在 Kubernete ...
随机推荐
- 8个前沿的 HTML5 & CSS3 效果【附源码下载】
作为一个前沿的 Web 开发者,对于 HTML5 和 CSS3 技术或多或少都有掌握.前几年这些新技术刚萌芽的时候,开发者们已经使用它们来小试牛刀了,如今这些先进技术已经遍地开发,特别是在移动端大显身 ...
- 你真的精通 CSS 了?来挑战一下 CSS 选择器测验吧
CSS 选择器赋予 CSS 强大的 HTML 元素匹配功能.作为前端开发人员必须要掌握的一部分,可能基本的大家都知道.但是你真的精通 CSS 了吗?挑战一下 CSS 选择器测验就知道. 您可能感兴趣的 ...
- TextView显示html文件中的图片
fromHtml还有另一个重构:fromHtml(String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler) 而I ...
- Windows Azure HandBook (10) 测试本地网络到微软云的延迟
<Windows Azure Platform 系列文章目录> 之前遇到一些微软云的客户,在使用海外数据中心的时候,需要评估本地网络到微软云网络的延迟. 我们建议部署到微软云上的服务,离最 ...
- 一步一步开发Game服务器(一)
什么是服务器?对于很多人来说也许只是简单成为在服务器端运行的程序的确如此,服务器通常意义就是说在服务器端运行的程序而已.那么我们怎么理解和分析游戏服务器哪? 传统意义上来说,程序运行后,正常流程, 启 ...
- ansible入门
前言 最近看了一下ansible,挺火的一个配置管理工具,对比老大哥puppet,使用起来要简单一些,并且可以批量执行命令,对比同是python语言编写的saltstack,不需要安装客户端(基于pa ...
- VMware中网络设置之Bridged
1.设置linux虚拟机Bridged模式. 2.查找网关地址:点击虚拟机工具栏编辑---Virtual Network Editor,选中VMnet0,然后在Bridged to 下拉框中选择可以本 ...
- [开源 .NET 跨平台 数据采集 爬虫框架: DotnetSpider] [三] 配置式爬虫
[DotnetSpider 系列目录] 一.初衷与架构设计 二.基本使用 三.配置式爬虫 四.JSON数据解析与配置系统 上一篇介绍的基本的使用方式,虽然自由度很高,但是编写的代码相对还是挺多.于是框 ...
- 在Visual Studio中使用正则表达式匹配换行和批量替换
系统环境:Windows 8.1 Enterprise Update 2 x64 开发环境:Mircosoft Visual Studio Ultimate 2013 Update 2 RC 问题:如 ...
- 使用NuGet打包并发布至ProGet过程 (打包再次详解)【下篇】
一.前言 上篇[1]主要介绍了利用csproj文件使用NuGet打包至ProGet的过程,并附上了用于在Jenkins上运行的python脚本.本篇的主要内容分为以下几点: 1. Nuspec与Nup ...