jquery.map()方法的使用详解


Posted in Javascript onJuly 09, 2015

原型方法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方法简单分析完毕,能力有限错误之处望多多指正。

以上所述就是本文的全部内容了,希望大家能够喜欢。

Javascript 相关文章推荐
网上应用的一个不错common.js脚本
Aug 08 Javascript
jQuery多条件筛选如何实现
Nov 04 Javascript
js中用cssText设置css样式的简单方法
Sep 19 Javascript
jquery自定义表单验证插件
Oct 12 Javascript
关于angular js_$watch监控属性和对象详解
Apr 24 Javascript
详解vue axios中文文档
Sep 12 Javascript
用Webpack构建Vue项目的实践
Nov 07 Javascript
解决webpack+Vue引入iView找不到字体文件的问题
Sep 28 Javascript
koa2使用ejs和nunjucks作为模板引擎的使用
Nov 27 Javascript
利用Vue实现一个markdown编辑器实例代码
May 19 Javascript
vue的滚动条插件实现代码
Sep 07 Javascript
vue使用refs获取嵌套组件中的值过程
Mar 31 Vue.js
jQuery实现鼠标点击弹出渐变层的方法
Jul 09 #Javascript
javascript+ajax实现产品页面加载信息
Jul 09 #Javascript
浅谈JavaScript中null和undefined
Jul 09 #Javascript
兼容各大浏览器的JavaScript阻止事件冒泡代码
Jul 09 #Javascript
JavaScript包装对象使用详解
Jul 09 #Javascript
jquery实现表单验证并阻止非法提交
Jul 09 #Javascript
jQuery实现tab选项卡效果的方法
Jul 08 #Javascript
You might like
六酷社区论坛HOME页清新格调免费版 下载
2007/03/07 PHP
PHP字符串比较函数strcmp()和strcasecmp()使用总结
2014/11/19 PHP
制作个性化的WordPress登陆界面的实例教程
2016/05/21 PHP
In Javascript Class, how to call the prototype method.(three method)
2007/01/09 Javascript
基于jquery的图片幻灯展示源码
2012/07/15 Javascript
js 验证身份证信息有效性
2014/03/28 Javascript
JavaScript中解决多浏览器兼容性23个问题的快速解决方法
2016/05/19 Javascript
jQuery表单验证简单示例
2016/10/17 Javascript
Validform验证时可以为空否则按照指定格式验证
2017/10/20 Javascript
ES6 迭代器(Iterator)和 for.of循环使用方法学习(总结)
2018/02/08 Javascript
vue.js的computed,filter,get,set的用法及区别详解
2018/03/08 Javascript
详解使用VueJS开发项目中的兼容问题
2018/08/02 Javascript
jquery实现垂直手风琴导航栏
2020/02/18 jQuery
python3.4用循环往mysql5.7中写数据并输出的实现方法
2017/06/20 Python
用python实现将数组元素按从小到大的顺序排列方法
2018/07/02 Python
Python用于学习重要算法的模块pygorithm实例浅析
2018/08/16 Python
python语音识别实践之百度语音API
2018/08/30 Python
python编写计算器功能
2019/10/25 Python
浅谈tensorflow 中tf.concat()的使用
2020/02/07 Python
python 成功引入包但无法正常调用的解决
2020/03/09 Python
为什么说python更适合树莓派编程
2020/07/20 Python
Python实现画图软件功能方法详解
2020/07/28 Python
Python描述数据结构学习之哈夫曼树篇
2020/09/07 Python
Python 实现PS滤镜的旋涡特效
2020/12/03 Python
Canon佳能美国官方商店:购买数码相机、数码单反相机、镜头和打印机
2016/11/15 全球购物
数控技术应用个人求职信范文
2014/02/03 职场文书
公司寄语大全
2014/04/10 职场文书
爱心倡议书范文
2014/05/12 职场文书
三八妇女节趣味活动方案
2014/08/23 职场文书
重阳节演讲稿:尊敬帮助老人 弘扬传统美德
2014/09/25 职场文书
领导班子四风对照检查材料思想汇报
2014/09/26 职场文书
员工工作及收入证明
2014/10/28 职场文书
2014年企业党建工作总结
2014/12/18 职场文书
暑期社会实践新闻稿
2015/07/17 职场文书
学习计划是什么
2019/04/30 职场文书
React更新渲染原理深入分析
2022/12/24 Javascript