jQuery 源码分析(五) map函数 $.map和$.fn.map函数 详解

那年仲夏 提交于 2019-11-28 21:32:17

$.map() 函数用于使用指定函数处理数组中的每个元素(或对象的每个属性),并将处理结果封装为新的数组返回,该函数有三个参数,如下:

  elems   Array/Object类型 指定的需要处理的数组或对象。

  callback  遍历时执行的回调函数

  arg    参数,执行回调函数时传入的参数

callback函数执行时可以带两个参数,分别是遍历时对应的值和它的索引(对象来说则是键名),如果有返回值,则将返回值拼凑为一个数组

$.fn.map()返回值是一个jQuery对象,它也是调用$.map()来实现的,返回的数组最后又调用pushStack创建一个jQuery对象而已,如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="http://libs.baidu.com/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
    <p id="p1">文本1</p>
    <p id="p2">文本2</p>
    <h1 id="h1">标题1</h1>
    <h1 id="h2">标题2</h1>
    <script>
        var arr=[11,12,13,14]; 
        var a =$.map(arr,function(element,index){return index;});
        console.log(a);                         //输出:Array [ 0, 1, 2, 3 ]

        var b =$.map([p1,p2,h1,h2],function(elem,i){
            console.log(elem,i)                 //分别输出:<p id="p1">(这是节点的引用) 0、<p id="p1"> 1、<h1 id="h1"> 2、<h1 id="h2"> 3
            return elem.parentNode;
        })
        console.log(b)                          //输出:Array [ body, body, body, body ]

        var c = $('p').map(function(i,elem){return elem.parentNode});
        console.log(c.length)                   //输出:2
        console.log(c[0]===c[1])                //输出:true
        console.log(c[1]===document.body)           //输出:true
    </script>
</body>
</html>

 

 源码分析


writer by:大沙漠 QQ:22969969

和$.each()一样,$.map()也是通过$.extend()挂载到$.fn上的,如下:

  map: function( elems, callback, arg ) {       //对数组中的每个元素或对象的每个属性调用一个回调函数,并将回调函数的返回值放入一个新的数组
    var value, key, ret = [],                           //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 ) ) ;      //isArray表示参数elems是否是数组

    // Go through the array, translating each of the items to their
    if ( isArray ) {                                    //对于数组或类数组对象,则通过for 循环遍历下标,
      for ( ; i < length; i++ ) {
        value = callback( elems[ i ], i, arg );           //执行callback函数,参数分别是当前Object,当前Object的次序和arg

        if ( value != null ) {                            //如果回调函数的返回值不是null 和undefined,则把返回值放入结果集ret。
          ret[ ret.length ] = value;
        }
      }

    // Go through every key on the object,
    } else {                                            //对于对象,则通过for-in 循环遍历
      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 );               //调用方法concat()将ret转换为一个数组,并返回
  },

对于$.fn.map()来说,它是调用$.map来实现的,如下:

  map: function( callback ) {
    return this.pushStack( jQuery.map(this, function( elem, i ) {     //内部通过静态方法jQuery.map()和原型方法.pushStack()实现,
      return callback.call( elem, i, elem );
    }));
  },

pushStack之前已经介绍过了,就是创建一个新的jQuery对象而已,我们可以指定其中的DOM元素和selector属性。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!