js数组方法总结

  1. 数组的排序

sort()方法排序问题。

sort()方法是Array原型链上自带的方法。 默认排序顺序是根据字符串Unicode码点。

// sort 排序

let arr=[12,2,34,8,7,9,15]
console.log(arr.sort())   //  [12, 15, 2, 34, 7, 8, 9]

sort排序默认排序顺序是根据字符串Unicode码点来排序的。 在进行数组排序的时候经常不是我们想要的结果。

为此需要对sort()排序做一下修改。

// sort 排序改进版,适用于数组元素全是Number类型的排序

function sortNumber(a,b){
    return a-b
}

let arr=[12,2,34,8,7,9,15]

let arrAfterSort=arr.sort(sortNumber)

console.log(arrAfterSort)   //  [2, 7, 8, 9, 12, 15, 34]

上面的方法正确的做出了数组中按照从小到大的顺序进行排序。

如果需要从大到小排序,只需要将 sortNumber中改为b-a即可

语法

arr.sort([compareFunction])

参数

那个参数是指按照何种方式进行排序,如果参数为空,那就按照默认的unicode的方式进行排序。 就是最开始看到的那种排序方式。

返回值

排序后的数组。请注意,数组已原地排序,并且不进行复制。

描述

如果没有指明 compareFunction ,那么元素会按照转换为的字符串的诸个字符的Unicode位点进行排序。例如 "Banana" 会被排列到 "cherry" 之前。当数字按由小到大排序时,9 出现在 80 之前,但因为(没有指明 compareFunction),比较的数字会先被转换为字符串,所以在Unicode顺序上 "80" 要比 "9" 要靠前

如果指明了 compareFunction ,那么数组会按照调用该函数的返回值排序。即 a 和 b 是两个将要被比较的元素:

  • 如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;

  • 如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。

  • 如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前。

  • compareFunction(a, b) 必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。

上面排序一个元素全是Number类型的数组时候,可以使用函数表达式,更为方便。
代码如下:

// sort 排序改进版,函数表达式


let arr=[12,2,34,8,7,9,15]

arr.sort((a,b)=>a-b)

console.log(arr)      //  [2, 7, 8, 9, 12, 15, 34]

2.数组中按照对象的某个属性进行排序

方法如下

let goods=[
    {name: 'apple',price: 21},
    {name: 'huawei',price: 12},
    {name: 'samsung',price: 7},
    {name: 'xiaomi', price: 16}
]

let goodsAfterSort=goods.sort((a,b)=>a.price-b.price)

console.log(goodsAfterSort)
数组中包含元素,按照元素属性值排序

上面就实现了数组元素中按照价格从低到高的顺序进行排序。

按照name进行排序

代码如下

let goods=[
    {name: 'apple',price: 21},  
    {name: 'samsung',price: 7},
    {name: 'huawei',price: 12},
    {name: 'xiaomi', price: 16}
]

let goodsAfterSort=goods.sort((a,b)=>{
    var nameA=a.name.toUpperCase()
    var nameB=b.name.toUpperCase()
    if(nameA<nameB){
        return -1
    }

    if(nameA>nameB){
        return 1
    }
    return 0;
})

console.log(goodsAfterSort)
实现了按照字母顺序进行排序



3.数组元素的增删改查

splice方法

语法

arrayObject.splice(index,deleteCount,item1,.....,itemX)

splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。

参数

index  必须
        指定修改的开始位置(从0计数)。如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位(从-1计数);如果负数的绝对值大于数组的长度,则表示开始位置为第0位。

howmany
        整数,表示要移除的数组元素的个数。

        如果 deleteCount 是 0或者负数,则不移除元素。这种情况下,至少应添加一个新元素。

        如果 deleteCount 大于start 之后的元素的总数,则从 start 后面的元素都将被删除(含第 start 位)。

        如果deleteCount被省略,则其相当于(arr.length - start)。

item1, ..., itemX
        要添加进数组的元素,从start 位置开始。如果不指定,则 splice() 将只删除数组元素。

        splice方法使用deleteCount参数来控制是删除还是添加:

        start参数是必须的,表示开始的位置

返回值

由被删除的元素组成的一个数组。如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组。

测试如下:

//  splice方法的使用

let arr=[1,2,3,4,5,6]

arr.splice(0,1)
console.log(arr)   //    [2,3,4,5,6]

可以看到arr变了,变成了经过splice后的数组。


//  splice方法的返回值

let arr=[1,2,3,4,5,6]

let t=arr.splice(0,1)
console.log(t)   //    [1]

splice方法的返回值是被切掉元素组成的数组。


//  splice方法删除并添加元素

let arr=[1,2,3,4,5,6]

arr.splice(2,1,'a','b')
console.log(arr)   //    [1, 2, "a", "b", 4, 5, 6]

从数组index为2的位置开始删除,删除1个元素。 并从这里塞进去2个新元素,arr变成了新数组


//  splice方法删除并添加元素

let arr=[1,2,3,4,5,6]

let t=arr.splice(2,1,'a','b')
console.log(t)   //   [3]

splice函数的返回值始终是被切掉元素组成的数组。


start参数为负数的情况。

//  index为负数的情况

let arr=[1,2,3,4,5,6]

arr.splice(-2,2)
console.log(arr)   //   [1,2,3,4]

表示从倒数第2个开始删除,删除2个,arr就变成了[1,2,3,4]


start参数为负数,且绝对值大于数组长度

//  start参数为负数,且绝对值大于数组长度

let arr=[1,2,3,4,5,6]

arr.splice(-8,2)
console.log(arr)   //   [3, 4, 5, 6]

start参数为负数,且绝对值大于数组长度时,则start相当于0


start参数为负数,且新增元素。

//  start参数为负数,且绝对值大于数组长度

let arr=[1,2,3,4,5,6]

arr.splice(-3,2,'c','d')
console.log(arr)   //   [1, 2, 3, "c", "d", 6]

上面表示从倒数第3个开始删除,删除2个元素,并且从倒数第3个位置新增2个元素c和d



slice方法

slice方法是定义在Array原型链上的方法。
Array.prototype.hasOwnProperty('slice') // true

slice() 方法返回一个新的数组对象,这一对象是一个由 begin和 end(不包括end)决定的原数组的浅拷贝。原始数组不会被改变。

语法

arr.slice()
arr.slice(begin)
arr.slice(begin, end)


参数

begin 可选
        从该索引处开始提取原数组中的元素(从0开始)。

end 可选
        在该索引处结束提取原数组元素(从0开始)。slice会提取原数组中索引从 begin 到 end 的所有元素(包含begin,但不包含end)。

        slice(1,4) 提取原数组中的第二个元素开始直到第四个元素的所有元素 (索引为 1, 2, 3的元素)。

        如果该参数为负数, 则它表示在原数组中的倒数第几个元素结束抽取。 slice(-2,-1)表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)。

        如果 end 被省略,则slice 会一直提取到原数组末尾。

        如果 end 大于数组长度,slice 也会一直提取到原数组末尾。

返回值

一个含有提取元素的新数组


例子:

//  数组中的slice方法

let arr=[1,2,3,4,5,6,7,8]

arr.slice(2,3)
console.log(arr)   //   [1,2,3,4,5,6,7,8]

可以看到经过slice后原数组不变


//  数组中的slice方法的返回值

let arr=[1,2,3,4,5,6,7,8]

let t=arr.slice(2,3)
console.log(t)   //   [3]

slice方法函数的返回值是一个新数组,含有提取元素的新数组。
本例中从index为2开始提取,提取到index为3,前面提到包含start但是不包含end,所以只提取了index为2的这一个元素

slice方法不会改变原数组




isArray

Array.isArray()用于确定传递的值是否是一个 Array

该方法是定义在Array对象上面的,不是定义在其原型链上的。

Array.hasOwnProperty('isArray') // true

Array.prototype.hasOwnProperty('isArray') // false

例子

Array.isArray([1,2,3])     // true

Array.isArray({foo: '123'})    // false

Array.isArray("foobar")    //  false

Array.isArray(undefined)   // false

Array.isArray(Array)    //  false

Array.isArray(Array.prototype)    // true

鲜为人知的事实:其实 Array.prototype 也是一个数组。

当检测Array实例时, Array.isArray 优于 instanceof,因为Array.isArray能检测iframes

下面的函数调用都返回 true

Array.isArray([]);      //  true
Array.isArray([1]);   //  true
Array.isArray(new Array());   // true

下面的函数调用都返回 false

Array.isArray();    // false
Array.isArray({});  // false
Array.isArray(null); // false
Array.isArray(undefined);  // false
Array.isArray(17);  // false
Array.isArray('Array');  // false
Array.isArray(true);  // false
Array.isArray(false); // false
Array.isArray({ __proto__: Array.prototype });  // false



Array.from

Array.from() 方法从一个类似数组或可迭代对象中创建一个新的数组实例


var str='javascript'
Array.from(str)   //   ["j", "a", "v", "a", "s", "c", "r", "i", "p", "t"]

...扩展运算符也能实现类似的功能


var str='javascript'
[...str]    //  ["j", "a", "v", "a", "s", "c", "r", "i", "p", "t"]

语法

Array.from(arrayLike[, mapFn[, thisArg]])

第二个参数是回调函数,新数组中的每个元素会执行该回调函数。


var str='javascript'

Array.from(str,item=>item+1)   //   ["j1", "a1", "v1", "a1", "s1", "c1", "r1", "i1", "p1", "t1"]

返回值

一个新的数组实例



Array.of

方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型

Array.of() 和 Array 构造函数之间的区别在于处理整数参数:

Array.of(7) 创建一个具有单个元素 7 的数组

而 Array(7) 创建一个长度为7的空数组

Array.of(7);       // [7] 
Array.of(1, 2, 3); // [1, 2, 3]

Array(7);          // [ , , , , , , ]
Array(1, 2, 3);    // [1, 2, 3]


concat

concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组


var array1 = ['a', 'b', 'c'];
var array2 = ['d', 'e', 'f'];

console.log(array1.concat(array2));    //   ["a", "b", "c", "d", "e", "f"]

语法

var new_array = old_array.concat(value1[, value2[, ...[, valueN]]])

参数

valueN
将数组和/或值连接成新数组

返回值

新的 Array 实例。

描述

concat方法创建一个新的数组,它由被调用的对象中的元素组成,每个参数的顺序依次是该参数的元素(如果参数是数组)或参数本身(如果参数不是数组)。它不会递归到嵌套数组参数中。

concat方法不会改变this或任何作为参数提供的数组,而是返回一个浅拷贝,它包含与原始数组相结合的相同元素的副本。 原始数组的元素将复制到新数组中,如下所示:

  • 对象引用(而不是实际对象):concat将对象引用复制到新数组中。 原始数组和新数组都引用相同的对象。 也就是说,如果引用的对象被修改,则更改对于新数组和原始数组都是可见的。 这包括也是数组的数组参数的元素。

  • 数据类型如字符串,数字和布尔(不是StringNumberBoolean 对象):concat将字符串和数字的值复制到新数组中。

例子

连接两个数组
var alpha = ['a', 'b', 'c'];
var numeric = [1, 2, 3];

alpha.concat(numeric);
// result in ['a', 'b', 'c', 1, 2, 3]

连接三个数组

var num1 = [1, 2, 3],
    num2 = [4, 5, 6],
    num3 = [7, 8, 9];

var nums = num1.concat(num2, num3);

console.log(nums); 
// results in [1, 2, 3, 4, 5, 6, 7, 8, 9]

将值连接到数组

以下代码将三个值连接到数组

var alpha = ['a', 'b', 'c'];

var alphaNumeric = alpha.concat(1, [2, 3]);

console.log(alphaNumeric); 
// results in ['a', 'b', 'c', 1, 2, 3]

合并嵌套数组

var num1 = [[1]];
var num2 = [2, [3]];

var nums = num1.concat(num2);

console.log(nums);
// results in [[1], 2, [3]]

// modify the first element of num1
num1[0].push(4);

console.log(nums);
// results in [[1, 4], 2, [3]]


copyWithin()

方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,而不修改其大小。

var array1 = [1, 2, 3, 4, 5];

// place at position 0 the element between position 3 and 4
console.log(array1.copyWithin(0, 3, 4));
// expected output: Array [4, 2, 3, 4, 5]

// place at position 1 the elements after position 3
console.log(array1.copyWithin(1, 3));
// expected output: Array [4, 4, 5, 4, 5]

上面的例子是说,从索引值为3的位置开始复制,复制到索引值为4的位置。 因为不包含end,所以实际上只复制了一个元素那就是索引值为3的,然后把它替换到target为0的位置,所以可以看到用4替换了数组第一个元素1,最后返回的结果是[4, 2, 3, 4, 5]

语法

arr.copyWithin(target[, start[, end]])

参数

target

   0 为基底的索引,复制序列到该位置。如果是负数,target 将从末尾开始计算。

   如果 target 大于等于 arr.length,将会不发生拷贝。如果 target 在 start 之后,复制的序列将被修改以符合 arr.length。

start

0 为基底的索引,开始复制元素的起始位置。如果是负数,start 将从末尾开始计算。

如果 start 被忽略,copyWithin 将会从0开始复制。

end

0 为基底的索引,开始复制元素的结束位置。copyWithin 将会拷贝到该位置,但不包括 end 这个位置的元素。如果是负数, end 将从末尾开始计算。

如果 end 被忽略,copyWithin 将会复制到 arr.length。

返回值

改变了的数组

该方法会改变原始数组,会变成改变后的数组。

var arr=[1,2,3,4,5,6]
arr.copyWithin(0,3,4)
console.log(arr)      //  [4, 2, 3, 4, 5, 6]



entries()

entries() 方法返回一个新的Array Iterator对象,该对象包含数组中每个索引的键/值对。

var arr=['a','b','c']
var t=arr.entries()
console.log(t)    //    Array Iterator {}

返回值是一个Array Iterator对象

Iterator对象都有next()方法

console.log(t.next())   //  {value: Array(2), done: false}

console.log(t.next().value)     //  [1, "b"]

console.log(t.next().value)   //  [2, "c"]
语法

arr.entries()

返回值

一个新的 Array 迭代器对象。

例子:

1、 Array Iterator

var arr = ["a", "b", "c"];
var iterator = arr.entries();
console.log(iterator);

/*Array Iterator {}
         __proto__:Array Iterator
         next:ƒ next()
         Symbol(Symbol.toStringTag):"Array Iterator"
         __proto__:Object
*/

2、iterator.next()

var arr = ["a", "b", "c"]; 
var iterator = arr.entries();
console.log(iterator.next());

/*{value: Array(2), done: false}
          done:false
          value:(2) [0, "a"]
           __proto__: Object
*/
// iterator.next()返回一个对象,对于有元素的数组,
// 是next{ value: Array(2), done: false };
// next.done 用于指示迭代器是否完成:在每次迭代时进行更新而且都是false,
// 直到迭代器结束done才是true。
// next.value是一个["key":"value"]的数组,是返回的迭代器中的元素值。

3、iterator.next方法运行

var arr = ["a", "b", "c"];
var iter = arr.entries();
var a = [];

// for(var i=0; i< arr.length; i++){   // 实际使用的是这个 
for(var i=0; i< arr.length+1; i++){    // 注意,是length+1,比数组的长度大
    var tem = iter.next();             // 每次迭代时更新next
    console.log(tem.done);             // 这里可以看到更新后的done都是false
    if(tem.done !== true){             // 遍历迭代器结束done才是true
        console.log(tem.value);
        a[i]=tem.value;
    }
}
    
console.log(a);                         // 遍历完毕,输出next.value的数组

4、二维数组按行排序

function sortArr(arr) {
    var goNext = true;
    var entries = arr.entries();
    while (goNext) {
        var result = entries.next();
        if (result.done !== true) {
            result.value[1].sort((a, b) => a - b);
            goNext = true;
        } else {
            goNext = false;
        }
    }
    return arr;
}

var arr = [[1,34],[456,2,3,44,234],[4567,1,4,5,6],[34,78,23,1]];
sortArr(arr);

/*(4) [Array(2), Array(5), Array(5), Array(4)]
    0:(2) [1, 34]
    1:(5) [2, 3, 44, 234, 456]
    2:(5) [1, 4, 5, 6, 4567]
    3:(4) [1, 23, 34, 78]
    length:4
    __proto__:Array(0)
*/

5、使用for…of 循环

var arr = ["a", "b", "c"];
var iterator = arr.entries();
// undefined

for (let e of iterator) {
    console.log(e);
}

// [0, "a"] 
// [1, "b"] 
// [2, "c"]



every()

every() 方法测试数组的所有元素是否都通过了指定函数的测试。


function isBelowThreshold(currentValue) {
  return currentValue < 40;
}

var array1 = [1, 30, 39, 29, 10, 13];

console.log(array1.every(isBelowThreshold));   // true


语法

arr.every(callback[, thisArg])

参数

  callback    用来测试每个元素的函数。

  thisArg    执行 callback 时使用的 this 值


描述

every 方法为数组中的每个元素执行一次 callback 函数,直到它找到一个使 callback 返回 false(表示可转换为布尔值 false 的值)的元素。如果发现了一个这样的元素,every 方法将会立即返回 false。否则,callback 为每一个元素返回 true,every 就会返回 true。callback 只会为那些已经被赋值的索引调用。不会为那些被删除或从来没被赋值的索引调用。

callback 被调用时传入三个参数:元素值,元素的索引,原数组。

如果为 every 提供一个 thisArg 参数,则该参数为调用 callback 时的 this 值。如果省略该参数,则 callback 被调用时的 this 值,在非严格模式下为全局对象,在严格模式下传入 undefined。

every 不会改变原数组。

every 遍历的元素范围在第一次调用 callback 之前就已确定了。在调用 every 之后添加到数组中的元素不会被 callback 访问到。如果数组中存在的元素被更改,则他们传入 callback 的值是 every 访问到他们那一刻的值。那些被删除的元素或从来未被赋值的元素将不会被访问到。

every 和数学中的"所有"类似,当所有的元素都符合条件才返回true。另外,空数组也是返回true。(空数组中所有元素都符合给定的条件,注:因为空数组没有元素)。

例子:
检测数组元素是否都大于10

var arr=[5,8,12,34,1,7]

arr.every(item=>item>10)  // false




fill

fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。


var array1 = [1, 2, 3, 4];

// fill with 0 from position 2 until position 4
console.log(array1.fill(0, 2, 4));
// expected output: [1, 2, 0, 0]

// fill with 5 from position 1
console.log(array1.fill(5, 1));
// expected output: [1, 5, 5, 5]

console.log(array1.fill(6));
// expected output: [6, 6, 6, 6]

语法

arr.fill(value[, start[, end]])

参数

value 用来填充数组元素的值

start 起始索引,默认值为0

end 终止索引,默认值为 this.length

返回值

修改后的数组。

描述

fill 方法接受三个参数 value, start 以及 end. start 和 end 参数是可选的, 其默认值分别为 0 和 this 对象的 length 属性值。

如果 start 是个负数, 则开始索引会被自动计算成为 length+start, 其中 length 是 this 对象的 length 属性值。如果 end 是个负数, 则结束索引会被自动计算成为 length+end。

fill 方法故意被设计成通用方法, 该方法不要求 this 是数组对象。

fill 方法是个可变方法, 它会改变调用它的 this 对象本身, 然后返回它, 而并不是返回一个副本。

当一个对象被传递给 fill方法的时候, 填充数组的是这个对象的引用。

例子:

[1, 2, 3].fill(4);               // [4, 4, 4]
[1, 2, 3].fill(4, 1);            // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2);         // [1, 4, 3]
[1, 2, 3].fill(4, 1, 1);         // [1, 2, 3]
[1, 2, 3].fill(4, 3, 3);         // [1, 2, 3]
[1, 2, 3].fill(4, -3, -2);       // [4, 2, 3]
[1, 2, 3].fill(4, NaN, NaN);     // [1, 2, 3]
[1, 2, 3].fill(4, 3, 5);         // [1, 2, 3]
Array(3).fill(4);                // [4, 4, 4]
[].fill.call({ length: 3 }, 4);  // {0: 4, 1: 4, 2: 4, length: 3}

// Objects by reference.
var arr = Array(3).fill({}) // [{}, {}, {}];
arr[0].hi = "hi"; // [{ hi: "hi" }, { hi: "hi" }, { hi: "hi" }]



filter

filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素

var words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(result);
// expected output: Array ["exuberant", "destruction", "present"]

语法

var new_array = arr.filter(callback(element[, index[, array]])[, thisArg])

参数

callback
用来测试数组的每个元素的函数。调用时使用参数 (element, index, array)。
返回true表示保留该元素(通过测试),false则不保留。它接受三个参数:

element   当前在数组中处理的元素

index 可选   正在处理元素在数组中的索引

array 可选   调用了filter的数组

thisArg 可选    执行 callback 时的用于 this 的值

返回值

一个新的通过测试的元素的集合的数组,如果没有通过测试则返回空数组

描述

filter 为数组中的每个元素调用一次 callback 函数,并利用所有使得 callback 返回 true 或 等价于 true 的值 的元素创建一个新数组。callback 只会在已经赋值的索引上被调用,对于那些已经被删除或者从未被赋值的索引不会被调用。那些没有通过 callback 测试的元素会被跳过,不会被包含在新数组中。

callback 被调用时传入三个参数:

  1. 元素的值
  2. 元素的索引
  3. 被遍历的数组

如果为 filter 提供一个 thisArg 参数,则它会被作为 callback 被调用时的 this 值。否则,callbackthis 值在非严格模式下将是全局对象,严格模式下为 undefined
callback 最终观察到的this值是根据通常函数所看到的 "this"的规则确定的。

filter 不会改变原数组,它返回过滤后的新数组。

filter 遍历的元素范围在第一次调用 callback 之前就已经确定了。在调用 filter 之后被添加到数组中的元素不会被 filter 遍历到。如果已经存在的元素被改变了,则他们传入 callback 的值是 filter 遍历到它们那一刻的值。被删除或从来未被赋值的元素不会被遍历到。

例子:


var filtered = [12, 5, 8, 130, 44].filter(item=>item>=10);      //  [12, 130, 44]



在数组中搜索

var fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];

/**
 * Array filters items based on search criteria (query)
 */
function filterItems(query) {
  return fruits.filter(function(el) {
      return el.toLowerCase().indexOf(query.toLowerCase()) > -1;
  })
}

console.log(filterItems('ap')); // ['apple', 'grapes']
console.log(filterItems('an')); // ['banana', 'mango', 'orange']


find

find() 方法返回数组中满足提供的测试函数的第一个元素的值

var array1 = [5, 12, 8, 130, 44];

var found = array1.find(function(element) {
  return element > 10;
});

console.log(found);
// expected output: 12

语法

arr.find(callback[, thisArg])

参数
callback
在数组每一项上执行的函数,接收 3 个参数:
element 当前遍历到的元素
index 当前遍历到的索引
array 数组本身

thisArg (可选) 指定 callback 的 this 参数

返回值

当某个元素通过 callback 的测试时,返回数组中的一个值,否则返回 undefined

描述

find 方法对数组中的每一项元素执行一次 callback 函数,直至有一个 callback 返回 true。当找到了这样一个元素后,该方法会立即返回这个元素的值,否则返回 undefined。注意 callback函数会为数组中的每个索引调用即从 0length - 1,而不仅仅是那些被赋值的索引,这意味着对于稀疏数组来说,该方法的效率要低于那些只遍历有值的索引的方法。

callback 函数带有3个参数:当前元素的值、当前元素的索引,以及数组本身。

如果提供了 thisArg 参数,那么它将作为每次 callback 函数执行时的上下文对象,否则上下文对象为 undefined

find 方法不会改变数组。

在第一次调用 callback函数时会确定元素的索引范围,因此在 find方法开始执行之后添加到数组的新元素将不会被 callback 函数访问到。如果数组中一个尚未被callback函数访问到的元素的值被callback函数所改变,那么当callback函数访问到它时,它的值是将是根据它在数组中的索引所访问到的当前值。被删除的元素仍旧会被访问到。

示例

用对象的属性查找数组里的对象

var inventory = [
    {name: 'apples', quantity: 2},
    {name: 'bananas', quantity: 0},
    {name: 'cherries', quantity: 5}
];

function findCherries(fruit) { 
    return fruit.name === 'cherries';
}

console.log(inventory.find(findCherries)); // { name: 'cherries', quantity: 5 }

寻找数组中的质数

function isPrime(element, index, array) {
  var start = 2;
  while (start <= Math.sqrt(element)) {
    if (element % start++ < 1) {
      return false;
    }
  }
  return element > 1;
}

console.log([4, 6, 8, 12].find(isPrime)); // undefined, not found
console.log([4, 5, 8, 12].find(isPrime)); // 5


findIndex

findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。

var array1 = [5, 12, 8, 130, 44];

function findFirstLargeNumber(element) {
  return element > 13;
}

console.log(array1.findIndex(findFirstLargeNumber));
// expected output: 3

语法

arr.findIndex(callback[, thisArg])

参数

callback 针对数组中的每个元素, 都会执行该回调函数, 执行时会自动传入下面三个参数:
     element 当前的元素。
     index当前元素的索引。
     array调用findIndex的数组

thisArg 可选。执行callback时作为this对象的值

描述

findIndex方法对数组中的每个数组索引0..length-1(包括)执行一次callback函数,直到找到一个callback函数返回真实值(强制为true)的值。如果找到这样的元素,findIndex会立即返回该元素的索引。如果回调从不返回真值,或者数组的length为0,则findIndex返回-1。 与某些其他数组方法(如Array#some)不同,在稀疏数组中,即使对于数组中不存在的条目的索引也会调用回调函数。

回调函数调用时有三个参数:元素的值,元素的索引,以及被遍历的数组。

如果一个 thisArg 参数被提供给 findIndex, 它将会被当作this使用在每次回调函数被调用的时候。如果没有被提供,将会使用undefined

findIndex不会修改所调用的数组。

在第一次调用callback函数时会确定元素的索引范围,因此在findIndex方法开始执行之后添加到数组的新元素将不会被callback函数访问到。如果数组中一个尚未被callback函数访问到的元素的值被callback函数所改变,那么当callback函数访问到它时,它的值是将是根据它在数组中的索引所访问到的当前值。被删除的元素仍然会被访问到。

示例

以下示例查找数组中素数的元素的索引(如果不存在素数,则返回-1)

function isPrime(element, index, array) {
  var start = 2;
  while (start <= Math.sqrt(element)) {
    if (element % start++ < 1) {
      return false;
    }
  }
  return element > 1;
}

console.log([4, 6, 8, 12].findIndex(isPrime)); // -1, not found
console.log([4, 6, 7, 12].findIndex(isPrime)); // 2



flat

flat() 方法会递归到指定深度将所有子数组连接,并返回一个新数组

//  数组中的flat方法的

var arr1=[1,2,[3],[4]]

arr1.flat()

console.log(arr1.flat())   //  [1, 2, 3, 4]

语法

var newArray = arr.flat(depth)

示例

扁平化数组

var arr1 = [1, 2, [3, 4]];
arr1.flat(); 
// [1, 2, 3, 4]

var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]

var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]

扁平化与空项
flat()方法会移除数组中的空项

var arr4 = [1, 2, , 4, 5];
arr4.flat();
// [1, 2, 4, 5]


forEach

forEach() 方法对数组的每个元素执行一次提供的函数

var array1 = ['a', 'b', 'c'];

array1.forEach(function(element) {
  console.log(element);
});

// expected output: "a"
// expected output: "b"
// expected output: "c"

语法

array.forEach(callback(currentValue, index, array){
//do something
}, this)
array.forEach(callback[, thisArg])

参数
callback 为数组中每个元素执行的函数,该函数接收三个参数:
    currentValue 数组中正在处理的当前元素
    index (可选) 数组中正在处理的当前元素的索引
     array可选 forEach()方法正在操作的数组
     thisArg(可选)

返回值

undefined

描述

forEach 方法按升序为数组中含有效值的每一项执行一次callback 函数,那些已删除或者未初始化的项将被跳过(例如在稀疏数组上)。

callback 函数会被依次传入三个参数:

  • 数组当前项的值
  • 数组当前项的索引
  • 数组对象本身

如果给forEach传递了thisArg参数,当调用时,它将被传给callback 函数,作为它的this值。否则,将会传入 undefined 作为它的this值。callback函数最终可观察到this值,这取决于 函数观察到this的常用规则

forEach 遍历的范围在第一次调用 callback 前就会确定。调用forEach 后添加到数组中的项不会被 callback 访问到。如果已经存在的值被改变,则传递给 callback 的值是 forEach 遍历到他们那一刻的值。已删除的项不会被遍历到。如果已访问的元素在迭代时被删除了(例如使用 shift()) ,之后的元素将被跳过 - 参见下面的示例。

forEach() 为每个数组元素执行callback函数;不像map() 或者reduce() ,它总是返回 undefined值,并且不可链式调用。典型用例是在一个链的最后执行副作用。



includes

includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false

var array1 = [1, 2, 3];

console.log(array1.includes(2));
// expected output: true

var pets = ['cat', 'dog', 'bat'];

console.log(pets.includes('cat'));
// expected output: true

console.log(pets.includes('at'));
// expected output: false

语法

arr.includes(searchElement)
arr.includes(searchElement, fromIndex)

参数

searchElement 需要查找的元素值

fromIndex 从该索引处开始查找 searchElement。如果为负值,则按升序从 array.length - fromIndex 的索引开始搜索。默认为 0

返回值

一个Boolean 值

示例

[1, 2, 3].includes(2);     // true
[1, 2, 3].includes(4);     // false
[1, 2, 3].includes(3, 3);  // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true

fromIndex 大于等于数组长度

如果fromIndex 大于等于数组长度 ,则返回 false 。该数组不会被搜索

var arr = ['a', 'b', 'c'];

arr.includes('c', 3);   //false
arr.includes('c', 100); // false

计算出的索引小于 0
如果 fromIndex 为负值,计算出的索引将作为开始搜索searchElement的位置。如果计算出的索引小于 0,则整个数组都会被搜索。

// 数组长度是3
// fromIndex 是 -100
// computed index 是 3 + (-100) = -97

var arr = ['a', 'b', 'c'];

arr.includes('a', -100); // true
arr.includes('b', -100); // true
arr.includes('c', -100); // true

includes() 作为一个通用方法

includes() 方法有意设计为通用方法。它不要求this值是数组对象,所以它可以被用于其他类型的对象 (比如类数组对象)。下面的例子展示了 在函数的arguments对象上调用的includes() 方法。

(function() {
  console.log([].includes.call(arguments, 'a')); // true
  console.log([].includes.call(arguments, 'd')); // false
})('a','b','c');



indexOf

indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1

var beasts = ['ant', 'bison', 'camel', 'duck', 'bison'];

console.log(beasts.indexOf('bison'));
// expected output: 1

// start from index 2
console.log(beasts.indexOf('bison', 2));
// expected output: 4

console.log(beasts.indexOf('giraffe'));
// expected output: -1

语法

arr.indexOf(searchElement)
arr.indexOf(searchElement[, fromIndex = 0])

参数

searchElement 要查找的元素

fromIndex 开始查找的位置。如果该索引值大于或等于数组长度,意味着不会在数组里查找,返回-1。如果参数中提供的索引值是一个负值,则将其作为数组末尾的一个抵消,即-1表示从最后一个元素开始查找,-2表示从倒数第二个元素开始查找 ,以此类推。 注意:如果参数中提供的索引值是一个负值,并不改变其查找顺序,查找顺序仍然是从前向后查询数组。如果抵消后的索引值仍小于0,则整个数组都将会被查询。其默认值为0.

返回值

首个被找到的元素在数组中的索引位置; 若没有找到则返回 -1

示例

以下例子使用indexOf方法确定多个值在数组中的位置

var array = [2, 5, 9];
array.indexOf(2);     // 0
array.indexOf(7);     // -1
array.indexOf(9, 2);  // 2
array.indexOf(2, -1); // -1
array.indexOf(2, -3); // 0

找出指定元素出现的所有位置

var indices = [];
var array = ['a', 'b', 'a', 'c', 'a', 'd'];
var element = 'a';
var idx = array.indexOf(element);
while (idx != -1) {
  indices.push(idx);
  idx = array.indexOf(element, idx + 1);
}
console.log(indices);
// [0, 2, 4]

判断一个元素是否在数组里,不在则更新数组

function updateVegetablesCollection (veggies, veggie) {
    if (veggies.indexOf(veggie) === -1) {
        veggies.push(veggie);
        console.log('New veggies collection is : ' + veggies);
    } else if (veggies.indexOf(veggie) > -1) {
        console.log(veggie + ' already exists in the veggies collection.');
    }
}

var veggies = ['potato', 'tomato', 'chillies', 'green-pepper'];

// New veggies collection is : potato,tomato,chillies,green-papper,spinach
updateVegetablesCollection(veggies, 'spinach'); 
// spinach already exists in the veggies collection.
updateVegetablesCollection(veggies, 'spinach');


join

join() 方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。

var elements = ['Fire', 'Wind', 'Rain'];

console.log(elements.join());
// expected output: Fire,Wind,Rain

console.log(elements.join(''));
// expected output: FireWindRain

console.log(elements.join('-'));
// expected output: Fire-Wind-Rain

语法

str = arr.join()
// 默认为 ","
str = arr.join("")
// 分隔符 === 空字符串 ""
str = arr.join(separator)
// 分隔符

####### 参数

separator
    指定一个字符串来分隔数组的每个元素。
    如果需要(separator),将分隔符转换为字符串。
    如果省略(),数组元素用逗号分隔。默认为 ","。
    如果separator是空字符串(""),则所有元素之间都没有任何字符

返回值

一个所有数组元素连接的字符串。如果 arr.length 为0,则返回空字符串。

描述

所有的数组元素被转换成字符串,再用一个分隔符将这些字符串连接起来。如果元素是undefined 或者null, 则会转化成空字符串。

例子

使用四种不同的分隔符连接数组元素
下例首先创建了一个数组 a,包含有三个元素,然后用四种不同的分隔符连接所有数组元素。首先是默认的分隔符逗号,然后是一个逗号加空格,接下来是一个加号前后加空格,最后是一个空字符串

var a = ['Wind', 'Rain', 'Fire'];
var myVar1 = a.join();      // myVar1的值变为"Wind,Rain,Fire"
var myVar2 = a.join(', ');  // myVar2的值变为"Wind, Rain, Fire"
var myVar3 = a.join(' + '); // myVar3的值变为"Wind + Rain + Fire"
var myVar4 = a.join('');    // myVar4的值变为"WindRainFire"

连接类数组对象

下面的示例将连接类数组对象(arguments),通过在Array.prototype.join上调用Function.prototype.call

function f(a, b, c) {
  var s = Array.prototype.join.call(arguments);
  console.log(s); // '1,a,true'
}
f(1, 'a', true);


keys

keys() 方法返回一个包含数组中每个索引键的Array Iterator对象

var array1 = ['a', 'b', 'c'];
var iterator = array1.keys(); 

  
for (let key of iterator) {
  console.log(key); // expected output: 0 1 2
}

语法

arr.keys()

返回值

一个新的 Array 迭代器对象

var arr=[1,2,4,5,6,7,8,10]

console.log(arr.keys())

// Array Iterator {}
// __proto__: Array Iterator
// next: ƒ next()
// Symbol(Symbol.toStringTag): "Array Iterator"
// __proto__: Object

示例

索引迭代器会包含那些没有对应元素的索引

var arr = ["a", , "c"];
var sparseKeys = Object.keys(arr);
var denseKeys = [...arr.keys()];
console.log(sparseKeys); // ['0', '2']
console.log(denseKeys);  // [0, 1, 2]


lastIndexOf

lastIndexOf() 方法返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从 fromIndex 处开始。

var animals = ['Dodo', 'Tiger', 'Penguin', 'Dodo'];

console.log(animals.lastIndexOf('Dodo'));
// expected output: 3

console.log(animals.lastIndexOf('Tiger'));
// expected output: 1


语法

arr.lastIndexOf(searchElement[, fromIndex = arr.length - 1])

参数

searchElement
 被查找的元素

fromIndex
 从此位置开始逆向查找。默认为数组的长度减 1,即整个数组都被查找。如果该值大于或等于数组的长度,则整个数组会被查找。如果为负值,将其视为从数组末尾向前的偏移。即使该值为负,数组仍然会被从后向前查找。如果该值为负时,其绝对值大于数组长度,则方法返回 -1,即数组不会被查找

返回值

数组中最后一个元素的索引,如未找到返回-1

示例

var array = [2, 5, 9, 2];
var index = array.lastIndexOf(2);
// index is 3
index = array.lastIndexOf(7);
// index is -1
index = array.lastIndexOf(2, 3);
// index is 3
index = array.lastIndexOf(2, 2);
// index is 0
index = array.lastIndexOf(2, -2);
// index is 0
index = array.lastIndexOf(2, -1);
// index is 3


map
map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。

var array1 = [1, 4, 9, 16];

// pass a function to map
const map1 = array1.map(x => x * 2);

console.log(map1);
// expected output: Array [2, 8, 18, 32]


语法

var new_array = arr.map(function callback(currentValue[, index[, array]]) {
// Return element for new_array }[,
thisArg])

参数

callback
   currentValue
       callback 数组中正在处理的当前元素

   index | 可选
       callback 数组中正在处理的当前元素的索引。

   array | 可选
       callback map 方法被调用的数组。

   thisArg | 可选
       执行 callback 函数时使用的this 值。

返回值

一个新数组,每个元素都是回调函数的结果。

描述

map 方法会给原数组中的每个元素都按顺序调用一次 callback 函数。callback 每次执行后的返回值(包括 undefined)组合起来形成一个新数组。 callback 函数只会在有值的索引上被调用;那些从来没被赋过值或者使用 delete 删除的索引则不会被调用。

callback 函数会被自动传入三个参数:数组元素,元素索引,原数组本身。

如果 thisArg 参数有值,则每次 callback 函数被调用的时候,this 都会指向 thisArg参数上的这个对象。如果省略了 thisArg ``参数,``或者赋值为 nullundefined,则 this 指向全局对象 。

map不修改调用它的原数组本身(当然可以在 callback 执行时改变原数组)。

使用 map 方法处理数组时,数组元素的范围是在 callback 方法第一次调用之前就已经确定了。在 map 方法执行的过程中:原数组中新增加的元素将不会被 callback 访问到;若已经存在的元素被改变或删除了,则它们的传递到 callback 的值是 map 方法遍历到它们的那一时刻的值;而被删除的元素将不会被访问到。



最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,290评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,399评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,021评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,034评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,412评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,651评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,902评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,605评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,339评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,586评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,076评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,400评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,060评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,851评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,685评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,595评论 2 270

推荐阅读更多精彩内容