欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-04-15 15:43:40
$.map() 函数用于使用指定函数处理数组中的每个元素(或对象的每个属性),并将处理结果封装为新的数组返回,该函数有三个参数,如下: elems Array/Object类型 指定的需要处理的数组或对象。 callback 遍历时执行的回调函数 arg 参数,执行回调函数时传入的参数 callba ......

$.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属性。