編輯注:這篇文章講到數組的5個使用方法,目前我比較常用的有indexOf和forEach,其它則很少見,這些屬性熟記于心能夠給你平時的編碼帶來意想不到的方便,有點可惜的是在IE9以下都不支持這些方法,不過如果你是在移動端和現代瀏覽器上則不需要考慮這些兼容,另外微信小程序也支持這種寫法。 在ES5中,一共有9個Array方法 http://kangax.github.io/compat-table/es5/ 注* 九個方法
Array.prototype.indexOf Array.prototype.lastIndexOf Array.prototype.every Array.prototype.some Array.prototype.forEach Array.prototype.map Array.prototype.filter Array.prototype.reduce Array.prototype.reduceRight我將挑選5種方法,我個人認為是最有用的,很多開發者都會碰到。
1) indexOf
indexOf()方法返回在該數組中第一個找到的元素位置,如果它不存在則返回-1。 不使用indexOf時var arr = ['apple','orange','pear'], found = false; for(var i= 0, l = arr.length; i< l; i++){ if(arr[i] === 'orange'){ found = true; } } console.log("found:",found);使用后
var arr = ['apple','orange','pear']; console.log("found:", arr.indexOf("orange") != -1);
2) filter
該filter()方法創建一個新的匹配過濾條件的數組。 不用 filter() 時var arr = [ {"name":"apple", "count": 2}, {"name":"orange", "count": 5}, {"name":"pear", "count": 3}, {"name":"orange", "count": 16}, ]; var newArr = []; for(var i= 0, l = arr.length; i< l; i++){ if(arr[i].name === "orange" ){ newArr.push(arr[i]); } } console.log("Filter results:",newArr);用了 filter():
var arr = [ {"name":"apple", "count": 2}, {"name":"orange", "count": 5}, {"name":"pear", "count": 3}, {"name":"orange", "count": 16}, ]; var newArr = arr.filter(function(item){ return item.name === "orange"; }); console.log("Filter results:",newArr);
3) forEach()
forEach為每個元素執行對應的方法var arr = [1,2,3,4,5,6,7,8]; // Uses the usual "for" loop to iterate for(var i= 0, l = arr.length; i< l; i++){ console.log(arr[i]); } console.log("========================"); //Uses forEach to iterate arr.forEach(function(item,index){ console.log(item); });forEach是用來替換for循環的
4) map()
map()對數組的每個元素進行一定操作(映射)后,會返回一個新的數組, 不使用mapvar oldArr = [{first_name:"Colin",last_name:"Toh"},{first_name:"Addy",last_name:"Osmani"},{first_name:"Yehuda",last_name:"Katz"}]; function getNewArr(){ var newArr = []; for(var i= 0, l = oldArr.length; i< l; i++){ var item = oldArr[i]; item.full_name = [item.first_name,item.last_name].join(" "); newArr[i] = item; } return newArr; } console.log(getNewArr());使用map后
var oldArr = [{first_name:"Colin",last_name:"Toh"},{first_name:"Addy",last_name:"Osmani"},{first_name:"Yehuda",last_name:"Katz"}]; function getNewArr(){ return oldArr.map(function(item,index){ item.full_name = [item.first_name,item.last_name].join(" "); return item; }); } console.log(getNewArr());map()是處理服務器返回數據時是一個非常實用的函數。
5) reduce()
reduce()可以實現一個累加器的功能,將數組的每個值(從左到右)將其降低到一個值。 說實話剛開始理解這句話有點難度,它太抽象了。 場景: 統計一個數組中有多少個不重復的單詞 不使用reduce時var arr = ["apple","orange","apple","orange","pear","orange"]; function getWordCnt(){ var obj = {}; for(var i= 0, l = arr.length; i< l; i++){ var item = arr[i]; obj[item] = (obj[item] +1 ) || 1; } return obj; } console.log(getWordCnt());使用reduce()后
var arr = ["apple","orange","apple","orange","pear","orange"]; function getWordCnt(){ return arr.reduce(function(prev,next){ prev[next] = (prev[next] + 1) || 1; return prev; },{}); } console.log(getWordCnt());讓我先解釋一下我自己對reduce的理解。reduce(callback, initialValue)會傳入兩個變量?;卣{函數(callback)和初始值(initialValue)。假設函數它有個傳入參數,prev和next,index和array。prev和next你是必須要了解的。 一般來講prev是從數組中第一個元素開始的,next是第二個元素。但是當你傳入初始值(initialValue)后,第一個prev將是initivalValue,next將是數組中的第一個元素。 比如:
/* * 二者的區別,在console中運行一下即可知曉 */ var arr = ["apple","orange"]; function noPassValue(){ return arr.reduce(function(prev,next){ console.log("prev:",prev); console.log("next:",next); return prev + " " +next; }); } function passValue(){ return arr.reduce(function(prev,next){ console.log("prev:",prev); console.log("next:",next); prev[next] = 1; return prev; },{}); } console.log("No Additional parameter:",noPassValue()); console.log("----------------"); console.log("With {} as an additional parameter:",passValue());原文地址: colintoh.com 如何兼容IE瀏覽器,看看這篇:讓ie以及老版本w3c瀏覽器 也支持ES5的 數組對象的 幾個新增方法. 寫了簡單注釋. 具體用法 請參考 ES5 手冊 .
// 模擬ES5 Array.prototype.forEach if (!Array.prototype.forEach) { Array.prototype.forEach = function(f, oThis) { if (!f || f.constructor != Function.toString()) return; oThis = oThis || window; for (var i = 0, len = this.length; i < len; i++) { f.call(oThis, this[i], i, this); //p1 上下文環境 p2 數組元素 p3 索引 p4 數組對象 } } }
//模擬 ES5 Array.prototype.filter if (!Array.prototype.filter) { Array.prototype.filter = function(f, oThis) { if (!f || f.constructor != Function.toString()) return; oThis = oThis || window; var a = []; for (var i = 0, len = this.length; i < len; i++) { if (f.call(oThis, this[i], i, this)) a.push(this[i]); } return a; } }
//模擬 ES5 Array.prototype.map if (!Array.prototype.map) { Array.prototype.map = function(f, oThis) { if (!f || f.constructor != Function.toString()) return; oThis = oThis || window; var a = []; for (var i = 0, len = this.length; i < len; i++) { a.push(f.call(oThis, this[i], i, this)); } return a; } }
//模擬 ES5 Array.prototype.every if (!Array.prototype.every) { Array.prototype.every = function(f, oThis) { if (!f || f.constructor != Function.toString()) return; oThis = oThis || window; for (var i = 0, len = this.length; i < len; i++) { if (!f.call(oThis, this[i], i, this)) return false; } return true; } }
//模擬 ES5 Array.prototype.some if (!Array.prototype.some) { Array.prototype.some = function(f, oThis) { if (!f || f.constructor != Function.toString()) return; oThis = oThis || window; for (var i = 0, len = this.length; i < len; i++) { if (f.call(oThis, this[i], i, this)) return true; } return false; } }要重點說一說的 indexOf lastIndexOf 兩個方法 .. 我只是實現了一個簡單版本.但修復了 一點點小問題 . 先看代碼
//模擬 ES5 Array.prototype.indexOf方法.并修復ff等其他實現 indexOf方法的瀏覽器中值類型于引用類型比較相等性一律返回false問題 Array.prototype.indexOf = function(obj) { for (var i = 0, len = this.length; i < len; i++) { if (compare(this[i], obj)) return i; } return -1; }
//模擬 ES5 Array.prototype.lastIndexOf方法.并修復ff等其他實現 indexOf方法的瀏覽器中值類型于引用類型比較相等性一律返回false問題 Array.prototype.lastIndexOf = function(obj) { for (var i = this.length - 1; i >= 0; i--) { if (compare(this[i], obj)) return i; } return -1; }是的. 注釋已經寫的明白.? 我這里之所以 用這個方法 覆蓋了 ES5 的方法原因在于
//比較對象是否于參數obj 相等.. function compare(obj1, obj2) { if (obj1 == null || obj2 == null) return (obj1 === obj2); return (obj1 == obj2 && obj1.constructor.toString() == obj2.constructor); }這個 compare方法 . 他解決了一個什么問題呢? 對了! 就是相等性判斷. 因為我發現? 原始版本的相等性判斷 居然會認為 1!=new Number(1)? 即 假如數組中存在一個 number對象 而我用 number 直接量去做比較 即使本應該相等. 也會返回false 這于 javascript? 引用類型 于值類型做 相等性運算時? 會調用引用類型 即對象的 valueOf方法 然后再去做比較 是相違背的. 說明 javascript 1.6 在實現 indexOf方法時 相等性判斷 他簡單的用了 === 即嚴格相等判斷 ... 那么我寫的compare 方法 的作用即 解決這個問題. 讓相等性判斷 遵循 javascript的原始規則... 說到這里 不得不提一下? 老外 在判斷 某個對象 為某特定類型時. 會使用 Object.porototyp.toString.call(this) 來做比較. 目的是為了防止 如 [1,2,3].constructor!=iframe.contentWindow.Array 這類情況... 其實大可不必那么麻煩 .? 我們只需要調用 兩邊的構造器對象 的其中一個的toString方法 返回一個?值類型的?string 偽對象即可. 這樣 另外一邊的引用類型 也會 自動調用 valueOf方法 于字符串做比較.. 何必 搞的那么麻煩呢? 最后. 恩 總體來說 我非常喜歡 forEach? map filter 等等方法 . 好用的很. 由于其他幾個方法 都是類似的. 所以 一并寫出來了!