搜尋
首頁web前端js教程詳細介紹JavaScript數組中的22個常用方法的程式碼詳細介紹

前面的話

陣列總共有22種方法,本文將其分為物件繼承方法、陣列轉換方法、堆疊和佇列方法、陣列排序方法、陣列拼接方法、建立子數組方法、數組刪改方法、數組位置方法、數組歸併方法和數組迭代方法共10類來進行詳細介紹

對象繼承方法

數組是一種特殊的對象,繼承了物件Object的toString()、toLocaleString()和valueOf()方法【toString()】toString()方法傳回由陣列中每個值的字串形式拼接而成的一個以逗號分隔的字串[注意]該方法的回傳值與不使用任何參數呼叫join()方法傳回的字串相同

[1,2,3].toString();//'1,2,3'
['a','b','c'].toString();//'a,b,c'
[1,[2,'c']].toString();//'1,2,c'

由於alert()要接收字串參數,它會在後台呼叫toString ()方法,會得到與toString()方法相同的結果

alert([1,2,3]);//'1,2,3'

【toLocaleString()】toLocaleString()是toString()方法的本地化版本,它經常也會傳回與toString()方法相同的值,但也不總是如此。因為,它呼叫元素的是toLocaleString()方法將每個陣列元素轉換為字串

var person1 = {
    toLocaleString: function(){
        return 'Nikolaos';
    },
    toString: function(){
        return 'Nicholas';
    }
};
var person2 = {
    toLocaleString: function(){
        return 'Grigorios';
    },
    toString: function(){
        return 'Greg';
    }
};
var people = [person1,person2];
console.log(people.toString());//'Nicholas,Greg'
console.log(people.toLocaleString());//'Nikolaos,Grigorios'

如果陣列中的某一項的值是null或undefined,則該值在toLocaleString()和toString ()方法傳回的結果中以空字串表示

var colors = [1,undefined,2,null,3];
console.log(colors.toString());//'1,,2,,3'
console.log(colors.toLocaleString());//'1,,2,,3'

【valueOf()】valueOf()方法傳回陣列物件本身

var a = [1, 2, 3];
console.log(a.valueOf());// [1, 2, 3]
console.log(a.valueOf() instanceof Array);//true

陣列轉換方法

【join()】Array.join()方法是String.split()方法的逆向運算,後者是將字串分割成若干區塊來建立一個陣列陣列繼承的toLocaleString ()和toString()方法,在預設情況下都會以逗號分隔的字元形式傳回數組項;而join()方法可以使用不同的分隔符號來建構這個字串,join()方法只接收一個參數,用作分隔符號的字串,然後傳回包含所有陣列項目的字串如果不給join()方法傳入任何值,則使用逗號作為分隔符號

var a = [1,2,3];
console.log(a.join());//'1,2,3'
console.log(a.join(' '));//'1 2 3'
console.log(a.join(''));//'123'

var b = new Array(10);
b.join('-');//'---------',9个连字符组成的字符串

若join()方法的參數是undefined ,標準瀏覽器以逗號為分隔符號傳回字串,而IE7-瀏覽器以'undefined'為分隔符號傳回字串

//标准浏览器为'1,2,3';IE7-浏览器为'1undefined2undefined3'
var a = [1,2,3];
console.log(a.join(undefined));

如果數組中的某一項的值是null或undefined,則該值在join()方法傳回的結果中以空字串表示

var colors = [1,undefined,2,null,3];
console.log(colors.join());//'1,,2,,3'

該方法也可以用於類別數組物件上

console.log(Array.prototype.join.call('hello', '-'));// "h-e-l-l-o"
var obj = { 0: 'a', 1: 'b', length: 2 };
console.log(Array.prototype.join.call(obj, '-'));// 'a-b'

[注意]若物件沒有length屬性,就不是類別數組,也不能呼叫數組的方法

var obj = { 0: 'a', 1: 'b' };
console.log(typeof Array.prototype.join.call(obj, '-'));//''

堆疊和佇列方法

push()和pop()方法允許將陣列當作堆疊來使用。 unshift()和shift()方法的行為非常類似於push()和pop(),不一樣的是前者是在數組的頭部而非尾部進行元素的插入和刪除操作

棧是一種LIFO(Last-First-Out,後進先出)的資料結構,也就是最新加入的項最早被移除。而棧中項的插入(叫做推入)和移除(叫做彈出),只發生在一個位置-棧的頂端。 javascript為陣列特別提供了push()和pop()方法,以便實作類似堆疊的行為

佇列資料結構的存取規則是FIFO(first-in-first-out,先進先出)。佇列在清單的末端新增項,從清單的前端移除項目。結合使用shift()和push()方法,可以像使用佇列一樣使用陣列

【push()】

push()方法可以接收任意數量的參數,把它們逐一加到數組末尾,並返回修改後數組的長度。所以,該數組會改變原始數組

var a = [];
console.log(a,a.push(1));//[1] 1
console.log(a,a.push('a'));//[1,'a'] 2
console.log(a,a.push(true, {}));//[1,'a',true,{}] 4
console.log(a,a.push([5,6]));//[1,'a',true,{},[5,6]] 5

如果需要合併兩個數組,可以使用apply方法

var a = [1, 2, 3];
var b = [4, 5, 6];
console.log(a,Array.prototype.push.apply(a, b));//[1,2,3,4,5,6] 6

[注意]如果使用call方法,則會把數組b整體看成一個參數

var a = [1, 2, 3];
var b = [4, 5, 6];
console.log(a,Array.prototype.push.call(a, b));//[1,2,3,[4,5,6]] 4

push()方法也可以向對象添加元素,添加後的對象變成類別數組對象,即新加入元素的鍵對應數組的索引,並且對像有一個length屬性

var obj = {a: 1};
console.log(obj,[].push.call(obj, 2));// {a:1, 0:2, length: 1}
console.log(obj,[].push.call(obj, [3]));// {a:1, 0:2, 1:[3], length: 2}

【pop()】

pop()方法從陣列結尾移除最後一項,減少陣列的length值,然後傳回移除的項目。所以,該數組會改變原始數組

var a = ['a', 'b', 'c'];
console.log(a,a.pop()); // ['a', 'b'] 'c'

對空數組使用pop()方法,不會報錯,而是返回undefined

var a = [];
console.log(a,a.pop()); // [] undefined

【shift()】

shift()方法移除數組中的第一個項並傳回該項,同時數組的長度減1。所以,該數組會改變原始數組

var a = ['a', 'b', 'c'];
console.log(a,a.shift());//['b', 'c'] 'a'

對空數組使用shift()方法,不會報錯,而是返回undefined

var a = [];
console.log(a,a.shift());// [] undefined

【unshift()】

unshift()方法在陣列前端新增任意個項目並傳回新陣列長度。所以,該數組會改變原始數組

var a = ['a', 'b', 'c'];
console.log(a,a.unshift('x')); //['x', 'a', 'b', 'c'] 4

當使用多個參數來呼叫unshift()時,參數是一次插入的而非一次一個地插入。這意味著最終的數組中插入的元素的順序和它們在參數列表中的順序一致

var a = ['a', 'b', 'c'];
console.log(a,a.unshift('x','y','z')); //['x','y','z','a', 'b', 'c'] 6

[注意]在IE7-瀏覽器中,unshift()方法返回的總是undefined

#
//标准浏览器下,返回[1] 1;而IE7-浏览器下,返回[1] undefined
var a = [];
console.log(a,a.unshift(1));

陣列排序方法

陣列中存在兩個可以直接用來重新排序的方法: reverse()和sort()

【reverse()】

reverse()方法用來反轉數組的順序,傳回經過排序之後的陣列;而原始數組順序也會改變

var array = [1,2,4,3,5];
console.log(array,array.reverse());//[5,3,4,2,1] [5,3,4,2,1]
var array = ['str',true,3];
console.log(array,array.reverse());//[3,true,'str'] [3,true,'str']

【sort()】

默认情况下,sort()方法按字符串升序排列数组项,sort方法会调用每个数组项的toString()方法,然后比较得到的字符串排序,返回经过排序之后的数组,而原数组顺序也发生改变

var array = [1,2,4,3,5];
console.log(array,array.sort());//[1,2,3,4,5] [1,2,3,4,5]
var array = ['3str',3,2,'2'];
console.log(array,array.sort());//[2, "2", 3, "3str"] [2, "2", 3, "3str"]
var array = [1,5,10,50];
console.log(array,array.sort());//[1, 10, 5, 50] [1, 10, 5, 50]

如果数组包含undefined元素,它们会被排到数组的尾部

var array = ['3',3,undefined,2,'2'];
console.log(array,array.sort());//["2", 2, "3", 3, undefined] ["2", 2, "3", 3, undefined]

sort()方法可以接受一个比较函数作为参数,以便指定哪个值在哪个值的前面。比较函数接收两个参数,如果第一个参数应该位于第二个参数之前则返回一个负数,如果两个参数相等则返回0,如果第一个参数应该位于第二个参数之后则返回一个正数

function compare(value1,value2){
    if(value1 < value2){
        return -1;
    }else if(value1 > value2){
        return 1;
    }else{
        return 0;
    }
}
var array = [&#39;5px&#39;,50,1,10];
//当数字与字符串比较大小时,字符串&#39;5px&#39;会被转换成NaN,这样结果就是false
console.log(array.sort(compare));//["5px",1, 10, 50]

对于数值类型或valueOf()方法会返回数值类型的对象类型,比较函数可以简化

function compare(value1,value2){
    return value1 - value2;
}
var array = [&#39;5px&#39;,50,1,10];
console.log(array.sort(compare));//["5px",1,10,50]
var array = [5,50,1,10];
console.log(array.sort(compare));//[1,5,10,50]

如果对一个字符串数组执行不区分大小写的字母表排序,比较函数首先将参数转化为小写字符串再开始比较

a = [&#39;ant&#39;,&#39;Bug&#39;,&#39;cat&#39;,&#39;Dog&#39;];
a.sort();//[&#39;Bug&#39;,&#39;Dog&#39;,&#39;ant&#39;,&#39;cat&#39;];
a.sort(function(s,t){
    var a = s.toLowerCase();
    var b = t.toLowerCase();
    if(a < b)return -1;
    if(a > b)return 1;
    return 0;
});//[&#39;ant&#39;,&#39;bug&#39;,&#39;cat&#39;,&#39;dog&#39;]

【tips】使用sort()方法创建一个随机数组

function compare(){
    return Math.random() - 0.5;
}
var array = [1,2,3,4,5];
console.log(array.sort(compare));//[2,1,5,4,3]

数组拼接方法

【concat()】

concat()方法基于当前数组中的所有项创建一个新数组,先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。所以concat()不影响原数组

如果不给concat()方法传递参数时,它只是复制当前的数组;如果参数是一个或多个数组,则该方法会将这些数组中的每一项都添加到结果数组中;如果传递的值不是数组,这些值就会被简单地添加到结果数组的末尾

var numbers = [1,2];
console.log(numbers,numbers.concat(3,4));//[1,2] [1,2,3,4]
console.log(numbers,numbers.concat([5,4,3],[3,4,5],1,2));//[1,2] [1,2,5,4,3,3,4,5,1,2]
console.log(numbers,numbers.concat(4,[5,[6,7]]));//[1,2] [1,2,4,5,[6,7]]

如果不提供参数,concat()方法返回当前数组的一个浅拷贝。所谓“浅拷贝”,指的是如果数组成员包括复合类型的值(比如对象),则新数组拷贝的是该值的引用

//该方法实际只复制了数组的第一维,数组第一维存放的是第二维的引用,而第二维才是实际存放他们的内容
var numbers = [1,2];
var newNumbers = numbers.concat();
console.log(numbers,newNumbers);//[1,2] [1,2]
numbers[0] = 0;
console.log(numbers,newNumbers);//[0,2] [1,2]

var numbers = [[1,2]];
var newNumbers = numbers.concat();
console.log(numbers,newNumbers);//[[1,2]] [[1,2]]
numbers[0][0] = 0;
console.log(numbers,newNumbers);//[[0,2]] [[0,2]]

concat()方法也可以用于将对象合并为数组,但是必须借助call()方法

var newArray = Array.prototype.concat.call({ a: 1 }, { b: 2 })
console.log(newArray);// [{ a: 1 }, { b: 2 }]
console.log(newArray[0].a);//1

创建子数组方法

 【slice()】

slice()方法基于当前数组中的一个或多个项创建一个新数组,接受一个或两个参数,即要返回项的起始和结束位置,最后返回新数组,所以slice()不影响原数组

slice(start,end)方法需要两个参数start和end,返回这个数组中从start位置到(但不包含)end位置的一个子数组;如果end为undefined或不存在,则返回从start位置到数组结尾的所有项

如果start是负数,则start = max(length + start,0)

如果end是负数,则end = max(length + end,0)

start和end无法交换位置

如果没有参数,则返回原数组

var numbers = [1,2,3,4,5];
console.log(numbers.slice(2));//[3,4,5]
console.log(numbers.slice(2,undefined));//[3,4,5]
console.log(numbers.slice(2,3));//[3]
console.log(numbers.slice(2,1));//[]

console.log(numbers.slice(-3));//-3+5=2 -> [3,4,5]
console.log(numbers.slice(-8));//max(5 + -8,0)=0 -> [1,2,3,4,5]

console.log(numbers.slice(0,-3));//-3+5=2 -> [1,2]
console.log(numbers.slice(-2,-1));//-2+5=3;-1+5=4; -> [4]

如果不提供参数,slice()方法返回当前数组的一个浅拷贝

//该方法实际只复制了数组的第一维,数组第一维存放的是第二维的引用,而第二维才是实际存放他们的内容
var numbers = [1,2];
var newNumbers = numbers.slice();
console.log(numbers,newNumbers);//[1,2] [1,2]
numbers[0] = 0;
console.log(numbers,newNumbers);//[0,2] [1,2]

var numbers = [[1,2]];
var newNumbers = numbers.slice();
console.log(numbers,newNumbers);//[[1,2]] [[1,2]]
numbers[0][0] = 0;
console.log(numbers,newNumbers);//[[0,2]] [[0,2]]

slice()方法涉及到Number()转型函数的隐式类型转换,当start被转换为NaN时,相当于start = 0;当end被转换为NaN时(end为undefined除外),则输出空数组

var numbers = [1,2,3,4,5];
console.log(numbers.slice(NaN));//[1,2,3,4,5]
console.log(numbers.slice(0,NaN));//[]
console.log(numbers.slice(true,[3]));//[2,3]
console.log(numbers.slice(null,undefined));//[1,2,3,4,5]
console.log(numbers.slice({}));//[1,2,3,4,5]
console.log(numbers.slice(&#39;2&#39;,[5]));//[3,4,5]

可以使用slice()方法将类数组对象变成真正的数组

var arr = Array.prototype.slice.call(arrayLike);

Array.prototype.slice.call({ 0: &#39;a&#39;, 1: &#39;b&#39;, length: 2 })// [&#39;a&#39;, &#39;b&#39;]
Array.prototype.slice.call(document.querySelectorAll("p"));
Array.prototype.slice.call(arguments);

数组删改方法

【splice()】

splice()和slice()拥有非常相似的名字,但它们的功能却有本质的区别。splice()方法用于删除原数组的一部分成员,并可以在被删除的位置添加入新的数组成员,该方法会改变原数组

splice()返回一个由删除元素组成的数组,或者如果没有删除元素就返回一个空数组

splice()的第一个参数start指定了插入或删除的起始位置。如果start是负数,则start = max(length + start,0);如果start是NaN,则相当于start = 0

如果只提供一个元素,相当于将原数组在指定位置拆分成两个数组

var a = [1,2,3,4,5,6,7,8];
console.log(a,a.splice());// [1,2,3,4,5,6,7,8] []
var a = [1,2,3,4,5,6,7,8];
console.log(a,a.splice(4));// [1,2,3,4] [5,6,7,8]
var a = [1,2,3,4,5,6,7,8];
console.log(a,a.splice(-4));//-4+8=4; [1,2,3,4] [5,6,7,8]
var a = [1,2,3,4,5,6,7,8];
console.log(a,a.splice(-9));//max(-9+8,0)=0 [] [1,2,3,4,5,6,7,8]
var a = [1,2,3,4,5,6,7,8];
console.log(a,a.splice(NaN));//[] [1,2,3,4,5,6,7,8]

第二个参数number指定了应该从数组中删除的元素的个数。如果省略第二个参数,从起始点开始到数组结尾的所有元素都将被删除。如果number是负数或NaN或undefined,则number=0,因此不删除元素

var a = [1,2,3,4,5,6,7,8];
console.log(a,a.splice(0,2));// [3,4,5,6,7,8] [1,2]
var a = [1,2,3,4,5,6,7,8];
console.log(a,a.splice(10,2));// [1,2,3,4,5,6,7,8] []
var a = [1,2,3,4,5,6,7,8];
console.log(a,a.splice(1,100));// [1] [2,3,4,5,6,7,8]
var a = [1,2,3,4,5,6,7,8];
console.log(a,a.splice(1,-5));//[1,2,3,4,5,6,7,8] []
var a = [1,2,3,4,5,6,7,8];
console.log(a,a.splice(1,NaN));//[1,2,3,4,5,6,7,8] []
var a = [1,2,3,4,5,6,7,8];
console.log(a,a.splice(1,undefined));//[1,2,3,4,5,6,7,8] []

如果后面还有更多的参数,则表示这些就是要被插入数组的新元素

var a = [1,2,3,4,5];
console.log(a,a.splice(2,0,&#39;a&#39;,&#39;b&#39;));//[1,2,&#39;a&#39;,&#39;b&#39;,3,4,5] []
console.log(a,a.splice(2,2,[1,2],3));//[1,2,[1,2],3,3,4,5] [&#39;a&#39;,&#39;b&#39;]

数组位置方法

ES5为数组实例添加了两个位置方法:indexOf()、lastIndexOf()

【indexOf()】

indexOf(search,start)方法接收search和start两个参数,返回search首次出现的位置,如果没有找到则返回-1

search参数表示要搜索的项;使用严格相等运算符(===)进行比较

var arr = [1,2,3,&#39;1&#39;,&#39;2&#39;,&#39;3&#39;];
console.log(arr.indexOf(&#39;2&#39;));//4
console.log(arr.indexOf(3));//2
console.log(arr.indexOf(0));//-1

start参数表示该搜索的开始位置,该方法会隐式调用Number()转型函数,将start非数字值(undefined除外)转换为数字。若忽略该参数或该参数为undefined或NaN时,start = 0

var arr = [&#39;a&#39;,&#39;b&#39;,&#39;c&#39;,&#39;d&#39;,&#39;e&#39;,&#39;a&#39;,&#39;b&#39;];
console.log(arr.indexOf(&#39;a&#39;,undefined));//0
console.log(arr.indexOf(&#39;a&#39;,NaN));//0
console.log(arr.indexOf(&#39;a&#39;,1));//5
console.log(arr.indexOf(&#39;a&#39;,true));//5
console.log(arr.indexOf(&#39;a&#39;,-1));//max(0,-1+7)=6; -1
console.log(arr.indexOf(&#39;a&#39;,-5));//max(0,-5+7)=2; 5
console.log(arr.indexOf(&#39;a&#39;,-50));//max(0,-50+7)=0; 0
var person = {name: &#39;Nicholas&#39;};
var people = [{name: &#39;Nicholas&#39;}];
var morePeople = [person];
alert(people.indexOf(person));//-1,因为person和people[0]虽然值相同,但是是两个引用
alert(morePeople.indexOf(person));//0,因为person和morepeople[0]是同一个引用
alert(morePeople.indexOf({name: &#39;Nicholas&#39;}));//-1,因为不是同一个引用

indexOf()方法兼容写法

if (typeof Array.prototype.indexOf != "function") {
  Array.prototype.indexOf = function (searchElement, fromIndex) {
    var index = -1;
    fromIndex = fromIndex * 1 || 0;
    for (var k = 0, length = this.length; k < length; k++) {
      if (k >= fromIndex && this[k] === searchElement) {
          index = k;
          break;
      }
    }
    return index;
  };
}

【lastIndexOf()】

与indexOf()不同,lastIndexOf()从右向左查找

lastIndexOf(search,start)方法接收search和start两个参数,返回search第一次出现的位置,如果没有找到则返回-1

search参数表示要搜索的项;使用严格相等运算符(===)进行比较

var arr = [1,2,3,&#39;1&#39;,&#39;2&#39;,&#39;3&#39;];
console.log(arr.lastIndexOf(&#39;2&#39;));//4
console.log(arr.lastIndexOf(3));//2
console.log(arr.lastIndexOf(0));//-1

start表示该搜索的开始位置,该方法会隐式调用Number()转型函数,将start非数字值(undefined除外)转换为数。若忽略该参数或该参数为undefined或NaN时,start = 0

与字符串的lastIndexOf()方法不同,当search方法为负数时,search = max(0,length+search)

var arr = [&#39;a&#39;,&#39;b&#39;,&#39;c&#39;,&#39;d&#39;,&#39;e&#39;,&#39;a&#39;,&#39;b&#39;];
console.log(arr.lastIndexOf(&#39;b&#39;));//6
console.log(arr.lastIndexOf(&#39;b&#39;,undefined));//-1
console.log(arr.lastIndexOf(&#39;a&#39;,undefined));//0
console.log(arr.lastIndexOf(&#39;b&#39;,NaN));//-1
console.log(arr.lastIndexOf(&#39;b&#39;,1));//1
console.log(arr.lastIndexOf(&#39;b&#39;,-1));//max(0,-1+7)=6; 6
console.log(arr.lastIndexOf(&#39;b&#39;,-5));//max(0,-5+7)=2; 1
console.log(arr.lastIndexOf(&#39;b&#39;,-50));//max(0,-50+7)=0; -1

【tips】返回满足条件的项的所有索引值

可以通过循环调用indexOf()或lastIndexOf()来找到所有匹配的项

function allIndexOf(array,value){
    var result = [];
    var pos = array.indexOf(value);
    if(pos === -1){
        return -1;
    }
    while(pos > -1){
        result.push(pos);
        pos = array.indexOf(value,pos+1);
    }
    return result;
}
var array = [1,2,3,3,2,1];
console.log(allIndexOf(array,1));//[0,5]

lastIndexOf()方法兼容写法

if (typeof Array.prototype.lastIndexOf != "function") {
  Array.prototype.lastIndexOf = function (searchElement, fromIndex) {
    var index = -1, length = this.length;
    fromIndex = fromIndex * 1 || length - 1;
    for (var k = length - 1; k > -1; k-=1) {
        if (k <= fromIndex && this[k] === searchElement) {
            index = k;
            break;
        }
    }
    return index;
  };
}

数组归并方法

数组归并方法包括reduce()和reduceRight()方法两种,它们使用指定的函数将数组元素进行组合,生成单个值。这在函数式编程中是常见的操作,也可以称为“注入”和“折叠”

【reduce()】

reduce()方法需要两个参数。第一个是执行化简操作的函数。化简函数的任务就是用某种方法把两个值组合或化简为一个值,并返回化简后的值

化简函数接受四个参数,分别是:

【1】初始变量,默认为数组的第一个元素值。函数第一次执行后的返回值作为函数第二次执行的初始变量,依次类推

【2】当前变量,如果指定了第二个参数,则该变量为数组的第一个元素的值,否则,为第二个元素的值

【3】当前变量对应的元素在数组中的索引(从0开始)

【4】原数组对象

化简函数的这四个参数之中,只有前两个是必须的,后两个则是可选的

values.reduce(function(prev, cur, index, array){
   //todo
});

reduce()方法第二个(可选)的参数是一个传递给函数的初始值

var a = [1,2,3,4,5];
var sum = a.reduce(function(x,y){return x+y},0);//数组求和
var product = a.reduce(function(x,y){return x*y},1);//数组求积
var max = a.reduce(function(x,y){return (x>y)?x:y;});//求最大值
[1, 2, 3, 4, 5].reduce(function(prev, cur){
    console.log(prev, cur)
    return prev+ cur;
});
// 1 2
// 3 3
// 6 4
// 10 5
//最后结果:15
[1, 2, 3, 4, 5].reduce(function(prev, cur){
    console.log(prev, cur);
    return prev + cur;
},0);
// 0 1
// 1 2
// 3 3
// 6 4
// 10 5
//最后结果:15

[注意]reduce()方法的返回结果类型和传入的初始值相同

[1, 2, 3, 4, 5].reduce(function(prev, cur){
    console.log(prev.sum, cur);
    prev.sum = prev.sum + cur;
    return prev;
},{sum:0});
//0 1
//1 2
//3 3
//6 4
//10 5
//Object {sum: 15}

利用reduce()方法,可以写一个数组求和的sum方法

Array.prototype.sum = function (){
    return this.reduce(function (prev, cur){
        return prev + cur;
    })
};
[3,4,5,6,10].sum();// 28

由于reduce方法依次处理每个元素,所以实际上还可以用它来搜索某个元素。比如,找出长度最长的数组元素

function findLongest(entries) {
  return entries.reduce(function (prev, cur) {
    return cur.length > prev.length ? cur : prev;
  }, &#39;&#39;);
}
console.log(findLongest([1,2,3,&#39;ab&#39;,4,&#39;bcd&#39;,5,6785,4]));//&#39;bcd&#39;

可以利用reduce()方法,实现二维数组的扁平化

var matrix = [
  [1, 2],
  [3, 4],
  [5, 6]
];
// 二维数组扁平化
var flatten = matrix.reduce(function (prev, cur) {
  return prev.concat(cur);
});
console.log(flatten); // [1, 2, 3, 4, 5, 6]

在空数组上,不带初始值参数调用reduce()将导致类型错误异常。如果调用它的时候只有一个值——数组只有一个元素并且没有指定初始值,或者有一个空数组并且指定一个初始值——reduce()只是简单地返回那个值而不会调用化简函数

var arr = [];
arr.reduce(function(){});//Uncaught TypeError: Reduce of empty array with no initial value

var arr = [];
arr.reduce(function(){},1);//1

reduce()方法兼容写法

if (typeof Array.prototype.reduce != "function") {
  Array.prototype.reduce = function (callback, initialValue ) {
     var previous = initialValue, k = 0, length = this.length;
     if (typeof initialValue === "undefined") {
        previous = this[0];
        k = 1;
     }
    if (typeof callback === "function") {
      for (k; k < length; k++) {
         this.hasOwnProperty(k) && (previous = callback(previous, this[k], k, this));
      }
    }
    return previous;
  };
}

【reduceRight()】

reduceRight()的工作原理和reduce()一样,不同的是它按照数组索引从高到低(从右到左)处理数组,而不是从低到高

var values = [1,2,3,4,5];
var sum = values.reduceRight(function(prev, cur, index, array){
    console.log(prev,cur);
    return prev + cur;
});
console.log(sum);
//5 4
//9 3
//12 2
//14 1
//15

reduceRight()方法兼容写法

if (typeof Array.prototype.reduceRight != "function") {
  Array.prototype.reduceRight = function (callback, initialValue ) {
    var length = this.length, k = length - 1, previous = initialValue;
    if (typeof initialValue === "undefined") {
        previous = this[length - 1];
        k--;
    }
    if (typeof callback === "function") {
       for (k; k > -1; k-=1) {          
          this.hasOwnProperty(k) && (previous = callback(previous, this[k], k, this));
       }
    }
    return previous;
  };
}

数组迭代方法

ECMAScript5为数组定义了5个迭代方法。每个方法都接收两个参数:要在每一项上运行的函数和(可选的)运行该函数的作用域对象——影响this的值。传入这些方法中的函数会接收三个参数:数组项的值、该项在数组中的位置和数组对象本身。根据使用的方法不同,这个函数执行后的返回值可能会也可能不会影响访问的返回值

function(item,index,array){
    //todo
}

【map()】

map()方法对数组的每一项运行给定函数,返回每次函数调用的结果组成的数组

//f是array的每一个元素调用的函数。它的返回值成为返回数组的元素;o是f调用时的可选this值
array.map(f,o);
[1,2,3].map(function(item,index,arr){return item*item});//[1,4,9]
[1,2,3].map(function(item,index,arr){return item*index});//[0,2,6]

map()方法还可以接受第二个参数,表示回调函数执行时this所指向的对象

var arr = [&#39;a&#39;,&#39;b&#39;,&#39;c&#39;];
[1,2].map(function(item,index,arr){return this[item]},arr);//[&#39;b&#39;,&#39;c&#39;]

在实际使用的时候,可以利用map()方法方便获得对象数组中的特定属性值

var users = [{name:&#39;t1&#39;,email:&#39;t1@qq.com&#39;},{name:&#39;t2&#39;,email:&#39;t2@qq.com&#39;},{name:&#39;t3&#39;,email:&#39;t3@qq.com&#39;}];
console.log(users.map(function(item,index,arr){return item.email}));//["t1@qq.com", "t2@qq.com", "t3@qq.com"]

map()方法还可以用于类数组对象

Array.prototype.map.call(&#39;abc&#39;,function(item,index,arr){return item.toUpperCase()});//["A", "B", "C"]

对于稀疏数组,map()方法不会在实际上不存在元素的序号上调用函数

var a = [1,,3];
console.log(a.map(function(item,index,arr){return item*2;}));//[2, 2: 6]

map()方法兼容写法

if (typeof Array.prototype.map != "function") {
  Array.prototype.map = function (fn, context) {
    var arr = [];
    if (typeof fn === "function") {
      for (var k = 0, length = this.length; k < length; k++) {      
         arr.push(fn.call(context, this[k], k, this));
      }
    }
    return arr;
  };
}

forEach()

forEach()方法对数组中的每一项运行给定函数,这个方法没有返回值。本质上与for循环迭代数组一样。如果需要有返回值,一般使用map方法

[1,2,3,4].forEach(function(item,index,arr){
    console.log(item)
});
//1
//2
//3
//4

类似于如下的for循环

var array = [1, 2, 3, 4];
for (var k = 0, length = array.length; k < length; k++) {
    console.log(array[k]);
}

使用forEach()方法实现简单的加法

var sum = 0;
[1, 2, 3, 4].forEach(function (item, index, array) {
    sum += item;
});
console.log(sum);//10

forEach()方法除了接受一个必须的回调函数参数,第二个参数还可以接受一个可选的上下文参数(改变回调函数里面的this指向)

var out = [];
[1, 2, 3].forEach(function(elem){
  this.push(elem * elem);
}, out);
console.log(out);// [1, 4, 9]

第二个参数对于多层this非常有用,因为多层this通常指向是不一致的,可以使用forEach()方法的第二个参数固定this

var obj = {
  name: &#39;张三&#39;,
  times: [1, 2, 3],
  print: function () {
  //该this指向obj
      console.log(this);
    this.times.forEach(function (n) {
    //该this指向window
      console.log(this);
    });
  }
};
obj.print();
var obj = {
  name: &#39;张三&#39;,
  times: [1, 2, 3],
  print: function () {
  //该this指向obj
      console.log(this);
    this.times.forEach(function (n) {
    //该this同样指向obj
      console.log(this);
    },this);
  }
};
obj.print();

forEach()循环可以用于类数组对象

var str = &#39;abc&#39;;
Array.prototype.forEach.call(str, function(item, index, array) {
  console.log( item + &#39;:&#39; + index);
});
//a:0
//b:1
//c:2

与for循环不同,对于稀疏数组,forEach()方法不会在实际上不存在元素的序号上调用函数

var a = [1,2,3];
delete a[1];
for(var i = 0; i < a.length; i++){
    console.log(a[i]);
}
//1
//undefined
//3
a.forEach(function(item,index,arr){console.log(item)});
//1
//3

forEach()方法无法在所有元素都传递给调用的函数之前终止遍历。也就是说,没有像for循环中使用的相应的break语句。如果要提前终止,必须把forEach()方法放在一个try块中,并能抛出一个异常

for(var i = 0; i < 5; i++){
    if(i == 2) break;
}
console.log(i);//2
var a = [1,2,3,4,5];
console.log(a.forEach(function(item,index,arr){
    if(index == 2) break;//Uncaught SyntaxError: Illegal break statement
}));
var a = [1,2,3,4,5];
a.forEach(function(item,index,arr){
    try{
      if(item == 2) throw new Error;    
    }catch(e){
        console.log(item);
    }
});

forEach()方法兼容写法

if(typeof Array.prototype.forEach != &#39;function&#39;){
    Array.prototype.forEach = function(fn,context){
        for(var k = 0,length = this.length; k < length; k++){
            if(typeof fn === &#39;function&#39; && Object.prototype.hasOwnProperty.call(this,k)){
                fn.call(context,this[k],k,this);
            }
        }
    }
}

【filter()】

filter()方法对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组。该方法常用于查询符合条件的所有数组项

[1, 2, 3, 4, 5].filter(function (elem) {
  return (elem > 3);
});// [4, 5]    

[0, 1, &#39;a&#39;, false].filter(Boolean);// [1, "a"]

[1, 2, 3, 4, 5].filter(function (elem, index, arr) {
  return index % 2 === 0;
});// [1, 3, 5]

filter()方法还可以接受第二个参数,指定测试函数所在的上下文对象(this对象)

var Obj = function () {
  this.MAX = 3;
};
var myFilter = function (item) {
  if (item > this.MAX) {
    return true;
  }
};
var arr = [2, 8, 3, 4, 1, 3, 2, 9];
arr.filter(myFilter, new Obj());// [8, 4, 9]

filter()会跳过稀疏数组中缺少的元素,它的返回数组总是稠密的,所以可以压缩稀疏数组的空缺

var a = [1,2,,,,3,,,,4];
console.log(a.length);//10
var dense = a.filter(function(){return true;})
console.log(dense,dense.length);//[1,2,3,4] 4

如果要压缩空缺并删除undefined和null元素,可以这样使用filter()方法

var a = [1,2,,undefined,,3,,null,,4];
console.log(a.length);//10
var dense = a.filter(function(item){return item!= undefined;})
console.log(dense,dense.length);//[1,2,3,4] 4

filter()方法兼容写法

if (typeof Array.prototype.filter != "function") {
  Array.prototype.filter = function (fn, context) {
    var arr = [];
    if (typeof fn === "function") {
       for (var k = 0, length = this.length; k < length; k++) {
          fn.call(context, this[k], k, this) && arr.push(this[k]);
       }
    }
    return arr;
  };
}

【some()】

some()方法对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回true。并且当且仅当数值中的所有元素调用判定函数都返回false,它才返回false

a = [1,2,3,4,5];
a.some(function(elem, index, arr){return elem%2===0;})//true
a.some(isNaN);//false

在空数组上调用some()方法会返回false

[].some(function(){});//false

some()方法兼容写法

if (typeof Array.prototype.some != "function") {
  Array.prototype.some = function (fn, context) {
    var passed = false;
    if (typeof fn === "function") {
         for (var k = 0, length = this.length; k < length; k++) {
          if (passed === true) break;
          passed = !!fn.call(context, this[k], k, this);
      }
    }
    return passed;
  };
}

【every()】

every()方法对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回true;只要有一项返回false,则返回false

a = [1,2,3,4,5];
a.every(function(elem, index, arr){elem < 10;})//true
a.every(function(elem, index, arr){return elem%2 ===0;});//false

在空数组上调用every()方法会返回true

[].every(function(){});//true

every()方法兼容写法

if (typeof Array.prototype.every != "function") {
  Array.prototype.every = function (fn, context) {
    var passed = true;
    if (typeof fn === "function") {
       for (var k = 0, length = this.length; k < length; k++) {
          if (passed === false) break;
          passed = !!fn.call(context, this[k], k, this);
      }
    }
    return passed;
  };
}

总结

javascript数组方法特意定义为通用的,因此它们不仅应用在真正的数组而且在类数组对象上都能正确工作。这22种方法中,除了toString()和toLocaleString()以外的所有方法都是通用的

可以改变原数组的方法总共有7种:包括unshift()、shift()、push()、pop()这4种栈和队列方法,reverse()和sort()这2种数组排列方法,数组删改方法splice()

以上就是详细介绍JavaScript数组中的22个常用方法的代码详细介绍的内容,更多相关内容请关注PHP中文网(www.php.cn)!



陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JavaScript,C和瀏覽器之間的關係JavaScript,C和瀏覽器之間的關係May 01, 2025 am 12:06 AM

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr

node.js流帶打字稿node.js流帶打字稿Apr 30, 2025 am 08:22 AM

Node.js擅長於高效I/O,這在很大程度上要歸功於流。 流媒體匯總處理數據,避免內存過載 - 大型文件,網絡任務和實時應用程序的理想。將流與打字稿的類型安全結合起來創建POWE

Python vs. JavaScript:性能和效率注意事項Python vs. JavaScript:性能和效率注意事項Apr 30, 2025 am 12:08 AM

Python和JavaScript在性能和效率方面的差異主要體現在:1)Python作為解釋型語言,運行速度較慢,但開發效率高,適合快速原型開發;2)JavaScript在瀏覽器中受限於單線程,但在Node.js中可利用多線程和異步I/O提升性能,兩者在實際項目中各有優勢。

JavaScript的起源:探索其實施語言JavaScript的起源:探索其實施語言Apr 29, 2025 am 12:51 AM

JavaScript起源於1995年,由布蘭登·艾克創造,實現語言為C語言。 1.C語言為JavaScript提供了高性能和系統級編程能力。 2.JavaScript的內存管理和性能優化依賴於C語言。 3.C語言的跨平台特性幫助JavaScript在不同操作系統上高效運行。

幕後:什麼語言能力JavaScript?幕後:什麼語言能力JavaScript?Apr 28, 2025 am 12:01 AM

JavaScript在瀏覽器和Node.js環境中運行,依賴JavaScript引擎解析和執行代碼。 1)解析階段生成抽象語法樹(AST);2)編譯階段將AST轉換為字節碼或機器碼;3)執行階段執行編譯後的代碼。

Python和JavaScript的未來:趨勢和預測Python和JavaScript的未來:趨勢和預測Apr 27, 2025 am 12:21 AM

Python和JavaScript的未來趨勢包括:1.Python將鞏固在科學計算和AI領域的地位,2.JavaScript將推動Web技術發展,3.跨平台開發將成為熱門,4.性能優化將是重點。兩者都將繼續在各自領域擴展應用場景,並在性能上有更多突破。

Python vs. JavaScript:開發環境和工具Python vs. JavaScript:開發環境和工具Apr 26, 2025 am 12:09 AM

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

JavaScript是用C編寫的嗎?檢查證據JavaScript是用C編寫的嗎?檢查證據Apr 25, 2025 am 12:15 AM

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境