ARRAY

Array.png

Array的方法

属性:

1.Array.length
2.Array.prototype

方法:

  1. Array.from():从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例;返回一个新的数组实例

参数:(arrayLike[,mapfn,thisArg])

  • arrayLike:想要转化的类数组和可迭代对象
  • mapfn:如果指定了该参数,新数组中的每个元素会执行该回调函数
  • thisArg: 执行回调函数mapfn时this对象
console.log(Array.from('foo')); //=> Array ["f", "o", "o"]    将一个字符串转化成数组
console.log(Array.from([1, 2, 3], x => x + x));//=>[2,4,6]  

Array.from(obj, mapFn, thisArg) 就相当于 Array.from(obj).map(mapFn, thisArg),执行mapFn的重要一点就是需要是适当的类型(例如array),可调用map的类型

关于数组去重

function combine(){ 
    let arr = [].concat.apply([],arguments);  //没有去重复的新数组 
    return Array.from(new Set(arr));
} 
var m = [1, 2, 2], n = [2,3,3,4]; 
console.log(combine(m,n));  //=>[1,2,3]
//这里就涉及到apply方法   
//apply的介绍: [https://www.jianshu.com/p/33b06b83b03c](https://www.jianshu.com/p/33b06b83b03c)
//Set对象允许你存储任何类型的唯一值,无论是[原始值]或者是对象引用

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

Array.isArray([1, 2, 3]);  //=> true
Array.isArray({foo: 123}); //=> false
Array.isArray("foobar");   //=>false
Array.isArray(undefined);  //=> false

3.Array.of() 方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型; 返回一个新的Array实例

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

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

接下来是实例方法

常用方法

  1. concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组
const array1 = ['a', 'b', 'c'];
const array2 = ['d', 'e', 'f'];
const array3 = [1,2,3,4]
const array4 = array1.concat(array2,array3,5); //可接受多个参数,可以是数组或单个值

console.log(array1) //=>['a','b','c']
console.log(array4);//=>["a", "b", "c", "d", "e", "f", 1, 2, 3, 4,5]

10.reduce()方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。

reducer函数接受四个参数;常用的参数只有两个:acc 和 cur

  • Accumulator (acc) (累计器);表示上一次调用回调时的返回值,或者初始值 init
  • Current Value (cur) (当前值)
  • Current Index (idx) (当前索引)
  • Source Array (src) (源数组)

arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
特别说明:initialValue:作为第一次调用 callback函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素在没有初始值的空数组上调用 reduce 将报错

注意:回调函数第一次执行时,accumulator 和currentValue的取值有两种情况:

  • 如果调用reduce()时提供了initialValue,accumulator取值为initialValue,currentValue取数组中的第一个值
  • 如果没有提供 initialValue,那么accumulator取数组中的第一个值,currentValue取数组中的第二个值
例子1:计算数组各个值的和
const array1 = [1, 2, 3, 4];
const reducer = (accumulator, currentValue) => accumulator + currentValue;
// 1 + 2 + 3 + 4
console.log(array1.reduce(reducer));// expected output: 10
// 5 + 1 + 2 + 3 + 4
console.log(array1.reduce(reducer, 5));// 15
//等价于
console.log([1, 2, 3, 4].reduce((accumulator, currentValue)=>accumulator + currentValue,5))//=>15

例子2:累加对象数组中的值,必须提供初始值
var initialValue = 0;
var sum = [{x: 1}, {x:2}, {x:3}].reduce(
    (accumulator, currentValue) => accumulator + currentValue.x
    ,initialValue
);

console.log(sum) //= 6

例子3:将二维数组转化成一维数组
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
  function(a, b) {
  console.log(b)
    //让[]与b:[]数组拼接
    return a.concat(b);
  },
  []
);
//[0, 1, 2, 3, 4, 5]

例子4:计算数组中每个元素出现的次数
var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];

var countedNames = names.reduce(function (allNames, name) { 
  if (name in allNames) {
    allNames[name]++;
  }
  else {
    allNames[name] = 1;
  }
  return allNames;
}, {});
console.log(countedNames)//=>{ 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }

例子5:数组去重
var myArray = ['a', 'b', 'a', 'b', 'c', 'e', 'e', 'c', 'd', 'd', 'd', 'd'];
var myOrderedArray = myArray.reduce(function (accumulator, currentValue) {
  if (accumulator.indexOf(currentValue) === -1) {
    accumulator.push(currentValue);
  }
  return accumulator
}, [])

console.log(myOrderedArray);//=>["a", "b", "c", "e", "d"]
//数组使用indexOf
var a = ['a','b','a'];
console.log(a.indexOf('a'))//=>0
//数字去重,先用sort排序
let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
let result = arr.sort().reduce((init, current) => {
    if(init.length === 0 || init[init.length-1] !== current) {
        init.push(current);
    }
    return init;
}, []);
console.log(result); //=》[1,2,3,4,5]

涉外知识点:indexOf():方法可返回某个指定的字符串值在字符串中首次出现的位置;可以用于判断该元素是否存在于该数组中(-1表示不存在)

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

语法:arr.includes(valueToFind[, fromIndex])

参数:valueToFind:需要查找的元素值;使用includes()比较字符串和字符时是区分大小写
fromIndex:从fromIndex索引处开始查找valueToFind.如果为负值,则按升序从array.length+ fromIndex的索引开始搜索。默认为0。fromIndex 大于等于数组的长度,则会返回 false,且该数组不会被搜索。array.length+ fromIndex最终结果小于0,则整个数组都会被搜索

//例子1
[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
//例子2
var arr = ['a', 'b', 'c'];
arr.includes('c', 3);   // false
arr.includes('c', 100); // false
//例子3
var arr = ['a', 'b', 'c'];
arr.includes('a', -100); // true
arr.includes('b', -100); // true
arr.includes('c', -100); // true
arr.includes('a', -2); // false

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

arr.indexOf(searchElement[, fromIndex])
1.searchElement:要查找的元素
2.fromIndex:可选;开始查找的位置,如果该值>=数组长度,则不会查找,会返回-1;如果该值为负数,查询起始位置=length+fromIndex,查询位置还是从前向后查找,相当于则将其作为数组末尾的一个抵消,即-1标识从最后一个元素开始查找,-2则从倒数第二个元素开始查找...,如果抵消后的索引值仍然小于0,则整个数组都将会被查询。默认值为0

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

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

console.log(beasts.indexOf('bison'));//=> 1

// start from index 2
console.log(beasts.indexOf('bison', -2));// =>4

console.log(beasts.indexOf('giraffe'));// => -1

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

语法:arr.lastIndexOf(searchElement[, fromIndex])
参数:
1.searchElement,被查找的元素。
2.fromIndex 可选;从此位置开始逆向查找。默认为数组的长度减1,即整个数组都被查找。如果该值>=数组长度,则整个数组会被查找。如果为负值,将其视为从数组末尾向前的偏移。如果该值为负值时,其绝对值大于数组长度,则返回-1,数组不会被查找;其绝对值小于数组长度时,数组仍然会被从后向前查找;
返回值:数组中该元素最后一次出现的索引,如未找到返回-1

注意:lastIndexOf使用严格相等比较searchElement和数组中的元素

例子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
例子2
var indices = [];
var array = ['a', 'b', 'a', 'c', 'a', 'd'];
var element = 'a';
var idx = array.lastIndexOf(element);

while (idx != -1) {
  indices.push(idx);
  idx = (idx > 0 ? array.lastIndexOf(element, idx - 1) : -1);
}

console.log(indices);//=> [4, 2, 0];

17.join()方法将一个数组(或一个[类数组对象])的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符

语法:arr.join([separator])

参数:separator(可选):用来指定一个字符串来分割数组的每个需要,默认为",",如果是空字符串(""),则所有元素之间都没有任何字符

返回值:一个所有数组元素连接的字符串,如果arr.length为0,则返回空字符串
如果一个元素为undefined或者null,它会被转换成为空字符串

var a = ['Wind', 'Rain', 'Fire'];
var myVar1 = a.join();      //=>"Wind,Rain,Fire"
var myVar2 = a.join(', ');  //=>的值变为"Wind, Rain, Fire"
var myVar3 = a.join(' + '); //=>的值变为"Wind + Rain + Fire"
var myVar4 = a.join('');    //=>的值变为"WindRainFire"
例子2
function f(a, b, c) {
  var s = Array.prototype.join.call(arguments);
  console.log(s); // '1,a,true'
}
f(1, 'a', true);

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

语法:arr.keys()
返回值:一个新的 Array迭代器对象。

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

28.values() 方法返回一个新的 Array Iterator 对象,该对象包含数组每个索引的值

语法:arr.values()

返回值:一个新的 Array 迭代对象

注意:Array.prototype.values 是 Array.prototype[Symbol.iterator] 的默认实现。

例子1:当 next().done=true 或 currentIndex>length 时, for..of 循环结束
let arr = ['w', 'y', 'k', 'o', 'p'];
let eArr = arr.values();

for (let letter of eArr) {
  console.log(letter);
} //"a" "b" "c" "d"
例子2:使用 .next() 迭代
var arr = ['a', 'b', 'c', 'd', 'e'];
var iterator = arr.values(); 
iterator.next();               // Object { value: "a", done: false }
iterator.next().value;         // "b"
iterator.next()["value"];      // "c"
iterator.next();               // Object { value: "d", done: false }
iterator.next();               // Object { value: "e", done: false }
iterator.next();               // Object { value: undefined, done: true } 
iteraroe.next().value;         // undefined
例子3:数组迭代器中存储的是原数组的地址,而不是数组元素值;如果数组中元素改变,那么迭代器的值也会改变
var arr = ['a', 'b', 'c', 'd', 'e']; 
var iterator = arr.values();
console.log(iterator); // Array Iterator {  }
iterator.next().value; // "a"
arr[1] = 'n';                 
iterator.next().value; //  "n"

29.@@iterator属性和 Array.prototype.values()属性的初始值是同一个函数对象。

语法:arrSymbol.iterator

返回值:返回数组的iterator方法,默认情况下,会values()返回值相同,arr[Symbol.iterator]这会返回values函数

例子1:使用for...of循环
var arr = ['a', 'b', 'c', 'd', 'e'];
var eArr = arr[Symbol.iterator]();
// 浏览器必须支持 for...of 循环
for (let letter of eArr) {
  console.log(letter);
}
例子2:迭代
var arr = ['a', 'b', 'c', 'd', 'e'];
var eArr = arr[Symbol.iterator]();
console.log(eArr.next().value); // a
console.log(eArr.next().value); // b
console.log(eArr.next().value); // c
console.log(eArr.next().value); // d
console.log(eArr.next().value); // e
例子3:values()
var arr = ['a', 'b', 'c', 'd', 'e'];
var eArr = arr[Symbol.iterator]();
var value = arr.values();
console.log(eArr)
console.log(value)
console.log(...eArr)
console.log(...value)
console.log(eArr.next())
console.log(eArr.next().value)
console.log(value.next())
console.log(value.next().value)
image.png

21.reverse() 方法将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。该方法会改变原数组

语法:arr.reverse()
返回值:颠倒后的数组

例子1
const a = [1, 2, 3];
console.log(a); // [1, 2, 3]
a.reverse(); 
console.log(a); // [3, 2, 1]
例子2
const array1 = ['one', 'two', 'three'];
console.log('array1:', array1); //=> expected output: "array1:" Array ["one", "two", "three"]
const reversed = array1.reverse();
console.log('reversed:', reversed);//=> expected output: "reversed:" Array ["three", "two", "one"]
console.log('array1:', array1);//=> expected output: "array1:" Array ["three", "two", "one"]

25.sort()方法用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较他们的UTF-16代码单元值序列时构建

arr.sort([compareFunction])

compareFunction:可选;用来指定按某种顺序进行排列的函数。如果省略,元素按照转化为字符串的各个字符的Unicode位点进行排序

返回值:排序后的数组;数组已原地排序,并且不进行复制;将改变原数组的值。
注意:如果没有指明compareFunction,那么元素会按照转化为字符串的诸个字符的Unicode位点进行排序。

//比较函数
function compare(a, b) {
  if (a < b ) {           // 按某种排序标准进行比较, a 小于 b
    return -1;
  }
  if (a > b ) {
    return 1;
  }
  // a must be equal to b
  return 0;
}

//比较数组非字符串
function compareNumbers(a, b) {
  return a - b;
}
例子1
var numbers = [4, 2, 5, 1, 3];
numbers.sort(function(a, b) {
  return a - b;
});
console.log(numbers);

//也可以写成:箭头函数
var numbers = [4, 2, 5, 1, 3]; 
numbers.sort((a, b) => a - b); 
console.log(numbers);
例子2:对象按照某个属性排序
var items = [
  { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'The', value: -12 },
  { name: 'Magnetic' },
  { name: 'Zeros', value: 37 }
];

// sort by value
items.sort(function (a, b) {
  return (a.value - b.value)
});

// sort by name
items.sort(function(a, b) {
  var nameA = a.name.toUpperCase(); // ignore upper and lowercase
  var nameB = b.name.toUpperCase(); // ignore upper and lowercase
  if (nameA < nameB) {
    return -1;
  }
  if (nameA > nameB) {
    return 1;
  }

  
// names must be equal

  return 0;
});
例子3:有无排序函数对比
var stringArray = ["Blue", "Humpback", "Beluga"];
var numericStringArray = ["80", "9", "700"];
var numberArray = [40, 1, 5, 200];
var mixedNumericArray = ["80", "9", "700", 40, 1, 5, 200];

function compareNumbers(a, b)
{
  return a - b;
}

console.log('stringArray:' + stringArray.join());//=》stringArray: Blue,Humpback,Beluga
console.log('Sorted:' + stringArray.sort());//=>Sorted: Beluga,Blue,Humpback

console.log('numberArray:' + numberArray.join());//=>numberArray: 40,1,5,200
console.log('Sorted without a compare function:'+ numberArray.sort());//=>Sorted without a compare function: 1,200,40,5
console.log('Sorted with compareNumbers:'+ numberArray.sort(compareNumbers));//=>Sorted with compareNumbers: 1,5,40,200

console.log('numericStringArray:'+ numericStringArray.join());//=>numericStringArray: 80,9,700
console.log('Sorted without a compare function:'+ numericStringArray.sort());//=>Sorted without a compare function: 700,80,9
console.log('Sorted with compareNumbers:'+ numericStringArray.sort(compareNumbers));//=>Sorted with compareNumbers: 9,80,700

console.log('mixedNumericArray:'+ mixedNumericArray.join());//=>mixedNumericArray: 80,9,700,40,1,5,200
console.log('Sorted without a compare function:'+ mixedNumericArray.sort());//=>Sorted without a compare function: 1,200,40,5,700,80,9
console.log('Sorted with compareNumbers:'+ mixedNumericArray.sort(compareNumbers));//=>Sorted with compareNumbers: 1,5,9,40,80,200,700
例子4:通过映射改善排序;当compareFunction可能需要对元素做多次映射以实现排序,尤其当compareFunction较为复杂,且元素较多的时候,比较函数可能导致很高的负载,这时可以使用map函数来辅助
// 需要被排序的数组
var list = ['Delta', 'alpha', 'CHARLIE', 'bravo'];

// 对需要排序的数字和位置的临时存储
var mapped = list.map(function(el, i) {
  return { index: i, value: el.toLowerCase() };
})

// 按照多个值排序数组
mapped.sort(function(a, b) {
  return +(a.value > b.value) || +(a.value === b.value) - 1;
});

// 根据索引得到排序的结果
var result = mapped.map(function(el){
  return list[el.index];
});
例子5:对非ASCII字符的字符串排序,需要使用String.localeCompare
var items = ['réservé', 'premier', 'cliché', 'communiqué', 'café', 'adieu'];
items.sort(function (a, b) {
  return a.localeCompare(b);
});

// items is ['adieu', 'café', 'cliché', 'communiqué', 'premier', 'réservé']

操作值的方法

22.shift() 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度

语法:arr.shift()
返回值:从数组中删除的元素; 如果数组为空则返回undefined

let myFish = ['angel', 'clown', 'mandarin', 'surgeon'];

console.log('调用 shift 之前: ' + myFish);//=> "调用 shift 之前: angel,clown,mandarin,surgeon"
var shifted = myFish.shift(); 
console.log('调用 shift 之后: ' + myFish); //=> "调用 shift 之后: clown,mandarin,surgeon" 
console.log('被删除的元素: ' + shifted); // =>"被删除的元素: angel"

27.unshift()方法将一个或多个元素添加到数组的开头,并返回该数组的新长度(该方法修改原有数组)。

语法:arr.unshift(element1, ..., elementN)

参数:elementN:要添加到数组开头的元素

返回值:arr.length

例子1:传入多个参数,同时调用和分开调用,将得到不同的结果
let arr = [4,5,6];
arr.unshift(1,2,3);
console.log(arr); // [1, 2, 3, 4, 5, 6]

arr = [4,5,6]; // 重置数组
arr.unshift(1);
arr.unshift(2);
arr.unshift(3);
console.log(arr); // [3, 2, 1, 4, 5, 6]

20.push() 方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度。

语法:arr.push(element1, ..., elementN)
参数:elementN:被添加到数组末尾的元素
返回值:新的length属性值

注意:push方法根据length属性来决定从哪里开始插入给定的值

例子1
var sports = ["soccer", "baseball"];
var total = sports.push("football", "swimming");
console.log(sports); //=> ["soccer", "baseball", "football", "swimming"];
console.log(total);  //=>4
例子2
var vegetables = ['parsnip', 'potato'];
var moreVegs = ['celery', 'beetroot'];

// 将第二个数组融合进第一个数组
// 相当于 vegetables.push('celery', 'beetroot');
Array.prototype.push.apply(vegetables, moreVegs);

console.log(vegetables); 
// ['parsnip', 'potato', 'celery', 'beetroot']

例子2的注意点:第二个数组(如示例中的moreVegs)太大时不要使用这个方法来合并数组,因为事实上一个函数能够接受的参数个数是有限制的,过长时,会有超出javascript引擎的参数长度限制的风险

19.pop()方法从数组中删除最后一个元素,并返回该元素的值。此方法更改数组的长度。

语法:arr.pop()
返回值:从数组中删除的元素(当数组为空时返回undefined)。

注意:pop方法从一个数组中删除并返回最后一个元素;pop方法是根据length属性俩确定最后一个元素的位置,如果不包含length属性或length属性不能被转成一个数值,会将length设置为0,并返回undefined;如果一个空数组调用pop方法,则返回undefined

let myFish = ["angel", "clown", "mandarin", "surgeon"];

let popped = myFish.pop();

console.log(myFish); 
// ["angel", "clown", "mandarin"]

console.log(popped); 
// surgeon

26.splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。

语法:array.splice(start[, deleteCount[, item1[, item2[, ...]]]])

参数
1.start:指定修改的开始位置(从0计数);
如果start>arr.length,则从数组末尾开始添加内容;
如果start<0,则表示从arr.length-n开始
如果负数的绝对值大于数组长度,则表示开始位置为第0位
2.deleteCount:可选;表示要移除的元素的个数
如果deleteCount>start之后的元素总数,则从start后面的元素都将被删除(含start位)
如果deleteCount被省略了,或者deleteCount >= arr.length - start ,那么start之后的数组的所有元素都会被删除
如果deleteCount是0或者负数,则不移除元素,至少应该添加一个元素
3.item1, item2, ... 可选;要添加的元素从start位置开始,如果不指定,则只删除数组元素

返回值:由被删除的元素组成的一个数组,如果没有删除元素,则返回空数组

注意:如果添加进数组的个数不等于被删除的元素个数,数组的长度会发生相应的变化

例子1:添加元素
var myFish = ["angel", "clown", "mandarin", "sturgeon"];
var removed = myFish.splice(2, 0, "drum");

// 运算后的 myFish: ["angel", "clown", "drum", "mandarin", "sturgeon"]
// 被删除的元素: [], 没有元素被删除

var removed = myFish.splice(2, 0, 'drum', 'guitar');

// 运算后的 myFish: ["angel", "clown", "drum", "guitar", "mandarin", "sturgeon"]
例子2:删除元素
var myFish = ['angel', 'clown', 'drum', 'mandarin', 'sturgeon'];
var removed = myFish.splice(3, 1);

// 运算后的 myFish: ["angel", "clown", "drum", "sturgeon"]
// 被删除的元素: ["mandarin"]


var myFish = ['parrot', 'anemone', 'blue', 'trumpet', 'sturgeon'];
var removed = myFish.splice(myFish.length - 3, 2);

// 运算后的 myFish: ["parrot", "anemone", "sturgeon"]
// 被删除的元素: ["blue", "trumpet"]


var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];
var removed = myFish.splice(-2, 1);

// 运算后的 myFish: ["angel", "clown", "sturgeon"]
// 被删除的元素: ["mandarin"]

var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];
var removed = myFish.splice(2);

// 运算后的 myFish: ["angel", "clown"]
// 被删除的元素: ["mandarin", "sturgeon"]
例子3:添加并删除
var myFish = ['angel', 'clown', 'drum', 'sturgeon'];
var removed = myFish.splice(2, 1, "trumpet");

// 运算后的 myFish: ["angel", "clown", "trumpet", "sturgeon"]
// 被删除的元素: ["drum"]

var myFish = ['angel', 'clown', 'trumpet', 'sturgeon'];
var removed = myFish.splice(0, 2, 'parrot', 'anemone', 'blue');

// 运算后的 myFish: ["parrot", "anemone", "blue", "trumpet", "sturgeon"]
// 被删除的元素: ["angel", "clown"]

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

语法:arr.slice([begin[, end]])
参数:
begin:可选;
1 如果该参数为负数,则表示从原数组中的倒数第几个元素开始提取,slice(-2)表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素);
2.如果省略begin,则slice从索引0开始;
3.如果begin大于原数组的长度,则会返回空数组
end:可选;
1.如果该参数为负数, 则它表示在原数组中的倒数第几个元素结束抽取。 slice(-2,-1) 表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素);
2.如果 end 被省略,则 slice 会一直提取到原数组末尾;
3.如果 end 大于数组的长度,slice 也会一直提取到原数组末尾;
返回值:一个含有被提取元素的新数组
注意:slice 不会修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组;如果该元素是一个对象引用,则slice会拷贝这个对象引用到新的数组里,两个对象都引用同一个对象。添加新元素则不会受到影响

const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];

console.log(animals.slice(2));//=>["camel", "duck", "elephant"]
console.log(animals.slice(2, 4));//=>["camel", "duck"]
console.log(animals.slice(1, 5));//=> ["bison", "camel", "duck", "elephant"]

例子2:slice 方法可以用来将一个类数组(Array-like)对象/集合转换成一个新数组
function list() {
  return Array.prototype.slice.call(arguments);
}
var list1 = list(1, 2, 3); // [1, 2, 3]

注意:函数的参数传入argument是数组结构

例子3:引用对象
// 使用 slice 方法从 myCar 中创建一个 newCar。
var myHonda = { color: 'red', wheels: 4, engine: { cylinders: 4, size: 2.2 } };
var myCar = [myHonda, 2, "cherry condition", "purchased 1997"];
var newCar = myCar.slice(0, 2);

// 输出 myCar、newCar 以及各自的 myHonda 对象引用的 color 属性。
console.log(' myCar = ' + JSON.stringify(myCar));//=> myCar = [{color: 'red', wheels: 4, engine: {cylinders: 4, size: 2.2}}, 2, 'cherry condition', 'purchased 1997']
console.log('newCar = ' + JSON.stringify(newCar));//=>newCar = [{color: 'red', wheels: 4, engine: {cylinders: 4, size: 2.2}}, 2]
console.log(' myCar[0].color = ' + JSON.stringify(myCar[0].color));//=>myCar[0].color = red 
console.log('newCar[0].color = ' + JSON.stringify(newCar[0].color));//=>newCar[0].color = red

// 改变 myHonda 对象的 color 属性.
myHonda.color = 'purple';
console.log('The new color of my Honda is ' + myHonda.color);//=>The new color of my Honda is purple

//输出 myCar、newCar 中各自的 myHonda 对象引用的 color 属性。
console.log('myCar[0].color = ' + myCar[0].color);//=>myCar[0].color = purple
console.log('newCar[0].color = ' + newCar[0].color);//=>newCar[0].color = purple

循环数组

6.every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。

参数:callback[,thisArg] ;

  • callback是一个用来测试每个元素的函数,它可以接收三个参数
    • element用于测试的当前值。
    • index可选;用于测试的当前值的索引。
    • array可选;调用 every 的当前数组
//例子1
const array1 =[1,30,32,10,20]
console.log(array1.every(x=>x<40)); //=>true
//例子2
function isBigEnough(element, index, array) {
  return element >= 10;
}
[12, 5, 8, 130, 44].every(isBigEnough);   // false
[12, 54, 18, 130, 44].every(isBigEnough); // true

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

语法:var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])

参数:callback(element[, index[, array]])[, thisArg]

  • element:数组中当前正在处理的元素
  • index:可选;当前正在处理的元素索引
  • array:可选;调用了filter的数组本身
  • thisArg:执行callback时,用于this的值

返回值:一个新的、由通过测试的元素组成的数组,如果没有任何数组元素通过测试,则返回空数组

注意:filter为数组中的每个元素调用一次callback函数,并利用所有使得callback返回true或等价于true的值的元素创建一个新数组,callback只会在已经赋值的索引上被调用,对于没有索引或索引未被赋值不会调用filter不会改变原数组,他返回过滤后的新数组

//例子1
const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

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

console.log(result);//=>["exuberant", "destruction", "present"]
//例子2
function isBigEnough(element) {
  return element >= 10;
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);//=>[12, 130, 44] 
//等价于
var filtered = [12, 5, 8, 130, 44].filter(x=>x>=10);//=>[12, 130, 44]

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

var new_array = arr.map(function callback(currentValue[, index[, array]]) {
// Return element for new_array
}[, thisArg])
参数:callBack:生成新数组元素的函数

  • currentValue:callback数组中正在处理的当前元素
  • index:(可选)callback数组中正在处理的当前元素的索引
  • array:(可选)map方法调用的数组

thisAry:执行callback函数时值被用作this

返回值:回调函数的结果组成了新数组的每一个元素;map方法不修改调用它的原数组本身

//求原数组中对应数字的平方根
var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt); //=>[1, 2, 3]
//使用map重新格式化数组中的对象
var kvArray = [{key: 1, value: 10}, 
               {key: 2, value: 20}, 
               {key: 3, value: 30}];

var reformattedArray = kvArray.map(function(obj) { 
   var rObj = {};
   rObj[obj.key] = obj.value;
   return rObj;
});
console.log(reformattedArray)//=>[{1: 10}, {2: 20}, {3: 30}]
// String上使用 map 方法获取字符串中每个字符所对应的 ASCII 码组成的数组
var map = Array.prototype.map
var a = map.call("Hello World", function(x) { 
  return x.charCodeAt(0); 
})
console.log(a)//=>[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
//如何去遍历用 querySelectorAll 得到的动态对象集合
var elems = document.querySelectorAll('select option:checked');
var values = Array.prototype.map.call(elems, function(obj) {
  return obj.value;
});

document.querySelectorAll('select option:checked')  :获取文档中select option:checked的所有元素

注意:通常情况下,map方法中的callback函数只需要接受一个参数,就是被遍历的数组元素本身,但是这并不意味着map只给callback传了一个参数,例如下面的例子

["1", "2", "3"].map(parseInt);
实际输出为:[1,NaN,NaN]

parseInt经常被带着一个参数使用,但是这里接受两个。第一个参数是一个表达式,第二个参数是callback function的三个参数。

parseInt(string, radix) -> map(parseInt(value, index))
parseInt接收两个参数,而map的callback function的三个参数是:value、index、array;会将function的前两个参数传递给parseInt,导致计算错误
//解决错误
function returnInt(element) {
  return parseInt(element, 10);
}

['1', '2', '3'].map(returnInt); // [1, 2, 3]

['1', '2', '3'].map( str => parseInt(str) );//=>[1,2,3]

14.forEach() 方法对数组的每个元素执行一次给定的函数

arr.forEach(callback(currentValue [, index [, array]])[, thisArg])
参数如上

返回值:undefined

注意:
1.forEach不会直接改变调用它的对象,但是那个对象可能会被callback函数改变
2.除了抛出异常以外,没有办法中止或跳出forEach循环,
如果需要中止循环或跳出循环,可以使用以下方法
for...of或for...in循环
every()
some()
find()
findIndex()
这些数组方法可以对数组元素判断,以便确定是否需要继续遍历

24.some() 方法测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值

语法:arr.some(callback(element[, index[, array]])[, thisArg])

callback:用来测试每个元素的函数
1.element:数组中正在处理的元素
2.index:可选;数组中正在处理的元素的索引值
3.array:可选;some()被调用的函数
thisArg:可选;执行callback时使用的this值

返回值:数组中有至少一个元素通过回调函数的测试就返回true;所有元素都没有通过会叫函数的测试返回值才会返回false

注意:some()不会改变原数组

例子1
function isBiggerThan10(element, index, array) {
  return element > 10;
}

[2, 5, 8, 1, 4].some(isBiggerThan10);  // false
[12, 5, 8, 1, 4].some(isBiggerThan10); // true


//等价于
[2, 5, 8, 1, 4].some(x=>x>10); //=>false
[12, 5, 8, 1, 4].some(x=>x>10);//=>true
例子2:判断数组元素中是否存在某个值
var fruits = ['apple', 'banana', 'mango', 'guava'];

function checkAvailability(arr, val) {
  return arr.some(function(arrVal) {
    return val === arrVal;
  });
}

//等价于
function checkAvailability(arr, val) {
  return arr.some(arrVal=>val === arrVal;);
}

checkAvailability(fruits, 'kela');   // false
checkAvailability(fruits, 'banana'); // true

非常用

5.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 将从末尾开始计算
const array1 = ['a', 'b', 'c', 'd', 'e'];
console.log(array1.copyWithin(0, 3, 4));//=>["d", "b", "c", "d", "e"]  0代表从index=0开始黏贴,3代表要开始复制的index(包括该下标),4代表结束的index(不包括该下标)

console.log(array1.copyWithin(1, 3)); //=>Array ["d", "d", "e", "d", "e"]   1代表从下标为1的位置开始粘贴,3代表从下标为3的位置开始复制,直到结束
console.log(array1.copyWithin(4, 3, 4));//=>Array ["a", "b", "c", "d", "d"]  如果 target 在 start 之后,复制的序列将被修改以符合 arr.length

7.entries() 方法返回一个新的Array Iterator对象,该对象包含数组中每个索引的键/值对。
Array Iterator是对象,它的原型(proto:Array Iterator)上有一个next方法,可用用于遍历迭代器取得原数组的[key,value]

var a = ['a', 'b', 'c'];
var i = a.entries();
console.log(i.next().value);//=>[0, "a"]
console.log(i.next());//=>{value:[1,'b'];done:false}
console.log(i.next())//=>{value:[1,'b'];done:false}
console.log(i.next())//=>{value:undefined;done:true}

例子2:

var a = ['a', 'b', 'c'];
var i = a.entries();
console.log(i);
image.png

这里有一个涉外知识点Array Iterator

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

value[, start[, end]]

  • value:用来填充数组元素的值,要代替的值
  • start:可选;默认值为0;如果是负值,值就为length+start
  • end:可选;默认值为 this.length;如果为负数,值就为length+end
    当一个对象被传递给fill方法的时候,填充数组的是这个对象的引用;改变的是改变原数组的值
const array1 = [1, 2, 3, 4];
console.log(array1.fill(0, 2, 4));//=> [1, 2, 0, 0]
console.log(array1.fill(5, 1));//=>[1, 5, 5, 5]
console.log(array1.fill(6));//=>[6, 6, 6, 6]
//不能用于填充数据
console.log(array1.fill(7,4,5));//=> [6, 6, 6, 6]
//start为负数
console.log(array1.fill(5, -1));//=>[1, 2, 0, 5]  -1相当于length:4+ start:-1=3
//等价于
console.log(array1.fill(5, 3))//=>[1, 2, 0, 5]

11.flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

var newArray = arr.flat([depth]);depth指定要提取嵌套数组的结构深度,默认值为1;返回一个将数组于子数组中所有元素的新数组

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]

//使用 Infinity,可展开任意深度的嵌套数组
var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
//不使用Infinity
var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat();
image.png

image.png
//移除数组中的空项
var arr4 = [1, 2, , 4, 5];
arr4.flat();//=> [1, 2, 4, 5] 
//使用reduce和concat
var arr = [1, 2, [3, 4]];
// 展开一层数组
arr.flat();
// 等效于
arr.reduce((acc, val) => acc.concat(val), []);//=> [1, 2, 3, 4]

// 使用扩展运算符 ...
const flattened = arr => [].concat(...arr);

13.flatMap()方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与map 连着深度值为1的 flat几乎相同,但 flatMap通常在合并成一种方法的效率稍微高一些

var new_array = arr.flatMap(function callback(currentValue[, index[, array]]) {
// return element for new_array
}[, thisArg])
参数:callback:可以生成一个新数组中的元素的函数

- currentvalue:当前正在数组中处理的元素
  • index:(可选)数组中正在处理的当前元素的索引
  • array:(可选)被调用的map数组

thisArg:执行callback函数时使用的this值

返回值:返回一个新数组,其中每一个元素都是回调函数的结果,并且结构深度depth为1;flatMap方法和map方法和深度depth为1的flat几乎相同

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

arr1.map(x => [x * 2]); 
// [[2], [4], [6], [8]]

arr1.flatMap(x => x * 2);  
// [2, 4, 6, 8]

arr1.flatMap(x => [x * 2]);  
// [2, 4, 6, 8]

// only one level is flattened
arr1.flatMap(x => [[x * 2]]);
// [[2], [4], [6], [8]]
//例子2
let arr1 = ["it's Sunny in", "", "California"];

arr1.map(x => x.split(" "));
// [["it's","Sunny","in"],[""],["California"]]

arr1.flatMap(x => x.split(" "));
// ["it's","Sunny","in", "", "California"]

map中传入字符串会被当成数组进行处理
//例子3
let a = [5, 4, -3, 20, 17, -33, -4, 18]
//       |\  \  x   |  | \   x   x   |
//      [4,1, 4,   20, 16, 1,       18]

a.flatMap( (n) =>
  (n < 0) ?      [] :
  (n % 2 == 0) ? [n] :
                 [n-1, 1]
)
console.log(a)//=>[4, 1, 4, 20, 16, 1, 18]

//例子4
var arr = [1, 2, 3, 4];

arr.flatMap(x => [x, x * 2]);
// is equivalent to
arr.reduce((acc, x) => acc.concat([x, x * 2]), []);

MDN的地址

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