首頁 > web前端 > js教程 > 主體

jquery.map()方法的使用詳解_jquery

WBOY
發布: 2016-05-16 15:50:46
原創
1101 人瀏覽過

原型方法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.Array( elemsisArray( )這三個至少成立一個

可以拆分為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方法簡單分析完畢,能力有限錯誤之處望多多指正。

以上所述就是本文的全部內容了,希望大家能夠喜歡。

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板