js 数组的基本运算

一、数组的概念

数组是值的有序集合,每个值叫元素,并且每个值在数组中有对应的数字位置编号,也就是索引。js中的数组是弱类型,可以包含不同类型的元素,可以是对象或者其它数组。

var arr = [0, true, null, undefined, 'a', {a:1}, [1,2,3]]

 每个元素都有对应的索引

arr[0] //表示第一个元素,索引0,值为0

arr[3] //表示第4个元素,索引3, 值为undefined

arr[5].a // 访问第6个元素,它是个对象,可以继续访问里面的值,为1

arr[6][0] //访问数组里面的数组,值为1

二、数组的创建

1、字面量

var life = ['love', 'career', 'family', 'friend']

var info = [{name:'book', sex:'girl'}, {name:'books', sex:'boy'}]

var arr = ['blue', true, null, undefined, function(){}, 123]

var arrInArr = [[0, 1], [2, 5, 7]]

var commasArr0 = [1, , 2] // 1, undefined, 2

var commasArr1 = [,,] // undefined × 2

数组的长度,也就是length 在 0-4294967295(2^23 - 1) 之间

数组允许最后有一个多余的逗号,所以 commasArr1为两个undefined,一般这样写法不推崇,可读性差,老浏览器会有兼容性问题

2、new Array

var arr = new Array(); // []

var arrLength = new Array(100); // [empty × 100]

var arrLove = new Array(true, false, 'love', 123); // [true, false, 'love', 123]
//等价于 [true, false, 'love', 123]

var arrOf = Array.of(123); // [123] 为es6新特性

注意Array的构造函数 new 可以省略

三、数组的操作

1、push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度

var arr = [];

arr.push(1); // 1 

arr.push(2, 3, 4); // 4
//可以同时push多个值
arr.push() // 4
//也可以不传值,返回数组的长度,等价于arr.length
arr // [1, 2, 3, 4]

arr.push('aa') // 5
//等同于
arr[arr.length] = 'aa' // 'aa'

arr // [1, 2, 3, 4, 'aa']

arr.push(true?8:null) // 6
//括号里面可以使用三元运算
arr // [1, 2, 3, 4, 'aa', 8]

扩展

a. push()等价方法arr[arr.length] = value 注意两者返回值不同,push返回新数组长度,arr[arr.length]返回value本身

b. push()括号中可以使用三元运算

2、unshift() 方法可向数组的开头添加一个或多个元素,并返回新的长度

var arr = [];

arr.unshift(1); // 1 

arr.unshift(2, 3, 4); // 4
//可以同时unshift多个值, 以2为开头
arr.unshift() // 4
//也可以不传值,返回数组的长度,等价于arr.length
arr // [2, 3, 4, 1]

arr.unshift(true?6:null) // 5
//括号里面可以使用三元运算
arr // [6, 2, 3, 4, 1]

注释

a.unshift()方法会改变数组的长度

b.unshift()方法无法在Internet Explorer中正确地工作

3、pop() 方法用于删除并返回数组的最后一个元素

var arr = [];

var arr1 = [1, 2, 3];

arr.pop(); // undefined

arr; // []

arr1.pop(); // 3
//等同于
arr1.length -= 1; // 2
    
arr1; // [1, 2]
//相似于
delete arr1[arr1.length - 1]; //true
//但数组长度不变 arr1.length = 2
arr1; // [1, empty]

注意

a.pop()方法删除数组最后一个元素,把数组长度减1,并且返回删除的元素

b.数组是空,pop()方法不改变数组,返回undefined

c.pop()等价方法arr1.length -=1 两者返回值不同,pop()返回删除元素,arr1.length -=1 返回删除后的数组长度

4、shift() 方法用于删除并返回数组的第一个元素

var arr = [];

var arr1 = [1, 2, 3];

arr.shift(); // undefined

arr; // []

arr1.shift(); // 1

arr1; // [2, 3]
//相似于
delete arr1[0]; // true
//但数组的长度不变 arr1.length = 2
arr1; // [empty, 3]

注意

a.shift()方法删除数组第一个元素,把数组长度减1,并且返回删除的元素

b.数组是空,shift()方法不改变数组,返回undefined

5、splice()方法从数组中添加/删除元素,然后返回被删除的元素

arrayObject.splice(index, deleteNum, addElement1, ......, addElementX)

var arr1 = [1, 2, 3];

arr1.splice(); // []
//不带参数时,不改变原来的数组
arr1; // [1, 2, 3]

arr1.splice(0); // [1, 2, 3]
//只有一个参数时, 删除从该参数起至数组末尾全部元素
arr1; // []

arr1.splice(0, 1); //[]
//因为arr1是空数组,所以没法删除,也不报错
arr1; // []

arr1.splice(1, 0,1); // []
//因为arr1是空数组,不存在index为1,所以从0开始添加元素
arr1; // [1]

arr1.splice(1, 0, 2, 3); // []

arr1; // [1, 2, 3]

arr1.splice(-1, 1, 4); // [3]
//当index为负数时,代表倒数第index个
arr1; // [1, 2, 4]

用splice实现,push,pop,unshift,shift方法,注意的是他们的返回值不同,splice返回的是数组

var arr1 = [1, 2, 3];

arr1.splice(0, 0, 0); // []
//等价于
arr1.unshift(0); // 4

arr1; // [0, 1, 2, 3]

arr1.splice(0, 1); // [0]
//等价于
arr1.shift(); // 0

arr1; // [1, 2, 3]

arr1.splice(arr1.length, 0, 4); // []
//等价于
arr1.push(4); // 4

arr1; // [1, 2, 3, 4]

arr1.splice(-1, 1); // [4]
//等价于
arr1.pop(); // 4

arr1; // [1, 2, 3]

注意

a.splice()方法改变原来的数组。

b.splice(index), index可以为负数,从数组结尾处开始。

c.splice(index), 删除或添加元素,包含index。

d.不填deleteNum, 删除从index到数组末尾全部元素。

6、slice()方法从数组中返回选定的元素

arrayObject.slice(start, end)

let arr1 = [1, 2, 3];

let arr2 = arr1.slice(); // [1, 2, 3]
//没有参数时,返回数组本身
arr2; // [1, 2, 3]

let arr3 = arr1.slice(0); // [1, 2, 3]
//没有end参数, 返回从start开始到数组末尾全部数组
arr3; // [1, 2, 3]

let arr4 = arr1.slice(1, 2); // [2]

arr4; // [2]

let arr5 = arr1.slice(-2, -1); //[2]
//从倒数第二个取到倒数第一个
arr5; //[2]

let arr6 = arr1.slice(-1, -2); //[]
//此时end参数小于start参数,取不到,返回空数组
arr6; // []
//以上操作不改变原数组
arr1; // [1, 2, 3]

注意

a.slice()方法不改变原数组

b.end参数不填,返回从start到数组结尾所有元素

c.start,end都可以为负数,从数组末尾开始选取元素

d.start,end无论正负,start要小于end,否则返回空数组

e.选取时,包含start, 不包含end

7、join()方法把数组中到所有元素放入一个字符串

arrayObject.join(separator)

let arr = [];

let arr1 = [1, 2, 3];

arr.join(); // ""
//空数组返回一个空字符串
let str = arr1.join(); // "1,2,3"

let str1 = arr1.join(undefined); // "1,2,3"
//省略参数或者为undefined时,使用逗号作为分隔符
str; // "1,2,3"

let arr2 = [1, 2, [3, [4, 5]]];

let str2 = arr2.join(); // "1, 2, 3, 4, 5" 
//如果是二维及多维数组,仍然可以把所有元素取出来,变成字符串
//等价于
arr2 + ''; // "1, 2, 3, 4, 5" 
str2; // "1, 2, 3, 4, 5"

let repeatA = new Array(5).join('a'); // "aaaa"

repeatA; // "aaaa"
//可以用join写个函数重复字符串
function repeatStr(str, n) {
    return new Array(n + 1).join(str)
}

注意

a.join()方法如果不带参数,将使用逗号作为分隔符, 等价于Array.prototype.toString()。

b.如果是二维及多维数组,仍然可以将所有元素转化为字符串。

8、reverse()方法用于颠倒数组中元素的顺序

arrayObject.reverse()

let arr1 = [1, 2, 3];

let arr = arr1.reverse(); // [3, 2, 1]
//改变原数组,并返回改变后的原数组
arr1; // [3, 2, 1]
arr;  // [3, 2, 1]

arr === arr1; //true
//返回的数组就是改变后的原来数组,他们代表着同一个数组

let arrInArr = [1, [2, 3], 4, 5];
//只颠倒一维中的数组
arrInArr.reverse(); // [5, 4, [2, 3], 1]

arrInArr; // [5, 4, [2, 3], 1]

注意

a.reverse()会改变原数组,并且不会创建新的数组,返回颠倒后的原数组。

b.只能颠倒一维中的数组,对二维及多维不做处理。

9、sort()方法用于对数组的元素进行排序

array.Object.sort(sortfunc) 

let arr = ['a', 'A', 'c', 'b'];
//默认排序顺序是根据字符串Unicode码
arr.sort(); // ['A', 'a', 'b', 'c']
//等价于
arr.sort(undefined); // ['A', 'a', 'b', 'c']

arr.sort(null); //Uncaught TypeError: The comparison function must be either a function or undefined
//不是函数或undefined会报错,TypeError

let num = [1, 20, 4, 31, 100];
//数字会先被转换为字符串,在按照Unicode顺序 "100" 要比 "20" 要靠前
num.sort(); // [1, 100, 20, 31, 4];
//所以两个数字比大小,如果都是字符串类型,会出错
'2' > '16'; // true
'2' >  16;  // false, 此时'2'会先转化为number类型在进行比较

let nums = num.sort(function(a, b) {
    return a - b
}); // [1, 4, 20, 31, 100]
//从小到大排序
num === nums; // true
//改变原数组,返回改变后的原数组

let age = [{age:8}, {age:23}, {age:21}];
//对数组中的对象排序
age.sort((a, b) => (a.age - b.age));

age; // [{age:8}, {age:21}, {age:23}]

注意

a.sort()会改变原数组,并且不会创建新的数组,返回排序后的原数组。

b.sortfunc必须是函数,可不填,或undefined。

c.两个数字比大小,必须有一个是number类型。

10、concat()方法用于合并两个或多个数组

arrayObject.concat(value1, value2…, valueX)

let arr1 = [1, 2, 3];

let arr2 = arr1.concat(); //[1, 2, 3]
//不加参数,返回一个和原数组相同的数组
arr2; // [1, 2, 3]

arr1 === arr2; // false, 说明创建了一个新数组

let arr3 = arr1.concat(4); // [1, 2, 3, 4]
//不改变原数组,返回一个新数组
arr1; // [1, 2, 3]

arr3; // [1, 2, 3, 4]

arr1.concat([4, 5], 6); // [1, 2, 3, 4, 5, 6]
//合并两个数组和一个值
arr1.concat([[4, 5], 6]); // [1, 2, 3, [4, 5], 6]
//合并两个数组,不会把数组里面的数组解析出来

注意

a.不会更改现有数组,而是返回一个新数组

b.将数组和数组或值连接成新数组

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

arrayObject.forEach(func(currentValue, index, array), thisArg)

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

array1.forEach(function(item, index, array){
    console.log(item, index, array, this)
}); // undefined
//不传thisArg参数, this指向全局
// 'a' 0 ['a', 'b', 'c'] window
// 'b' 1 ['a', 'b', 'c'] window
// 'c' 2 ['a', 'b', 'c'] window

let arr = [1, 2];

arr.forEach(v => console.log(v, this), {}); // undefined
// 1 window
// 2 window
//传入thisArg,但是使用箭头函数,this会指向全局

arr.length = 10; // 10

arr; // [1, 2, empty × 8]

delete arr[1]; // true

arr; // [1, empty × 9]

arr.forEach(v => console.log(v)); // undefined
//未初始化的项、已删除的项将被跳过
// 1

arr = arr.concat(2, 3); // [1, 2, 3]

arr.forEach((v, index, arr) => {
    if(index === 1) {
        arr.splice(1, 1)
    }
    console.log(v)
}); // undefined

// 1
// 2
//删除的是2,但是却打印出来了2,没打印出来3,
//因为传递给 func 的值是 forEach 遍历到他们那一刻的值,
//已访问的元素在迭代时被删除了,元素也将被跳过

arr; // [1, 3]

注意

a.forEach()返回值是undefined,使用return无效

b.没有办法中止或者跳出 forEach() 循环,除了抛出一个异常

c.递给 func 的值是 forEach 遍历到他们那一刻的值

d.已访问的元素被删除或在迭代时被删除或未初始化(如稀疏数组),元素将被跳过

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

arrayObject.map(func(currentValue, index, array), thisArg)

let arr = [1, 2, 3];

let arrmap = arr.map(function(value, index, array){
    console.log(value, index, array, this)
    return value + ''
}); // ['1', '2', '3']
// 1  0  [1, 2, 3] window
// 2  1  [1, 2, 3] window
// 3  2  [1, 2, 3] window
//原数组不变, 
//省略了thisArg参数,或者赋值为 null 或 undefined,则this指向全局对象
arrmap; // ['1', '2', '3']
arr; // [1, 2, 3]

let NumberArrmap = arrmap.map(Number); //[1, 2, 3]
//只需要传入Number函数即可
NumberArrmap; // [1, 2, 3]

arr[5] = 5;
arr; // [1, 2, 3, empty * 2, 5];

let str = arr.map(v => v + ''); // ['1', '2', '3', empty * 2, '5']
//没被赋过值或者使用 delete 删除的索引不会被调用

let arrs = arr.map((v, index) => {
    if(index === 0) {
        delete arr[1]
    }
    if (index === 1) {
        arr.push(6)
    }
    return v
}); // [1, empty, 3, empty * 2, 5]

arrs; // [1, empty, 3, empty * 2, 5]
arr; // [1, empty, 3, empty * 2, 5, 6]
//map 不修改调用它的原数组本身, 但在func中仍然可以修改,和forEach相同
//数组元素的范围是在func方法第一次调用之前就已经确定了,
//func方法执行过程中,新增的元素或删除到元素,不会被访问到

注意

a.map返回一个新的数组,如果没有return,将返回undefined,如果是未赋值或者被删除,则忽略

b.不改变调用它的原数组本身, 但在func中仍然可以修改

c.省略了 thisArg 参数,或者赋值为 null 或 undefined,则 this 指向全局对象,

d.如果func使用箭头函数,则会忽略thisArg参数,this指向全局对象,

e.数组元素的范围是在func方法第一次调用之前就已经确定,在func执行时,新增或删除,都不会被访问到

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

arrayObject.filter(func(currentValue, index, array), thisArg)

let arr = [1, 2, 3];

let arrf = arr.filter((value, index, array) => {
    console.log(value, index, array)
    return value > 1
});
// 1 0 [1, 2, 3]
// 2 1 [1, 2, 3]
// 3 2 [1, 2, 3]
//原数组不变
arr; // [1, 2, 3]
arrf; // [2, 3]

let arrf1 = arr.filter(v => v == 0);

//不存在符合的项目,返回空数组
arrf1; // []

注意

a.如果没有符合条件的项目,返回空数组

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

arrayObject.every(func(currentValue, index, array), thisArg)

let arr = [1, 2, 3];

let arr1 = arr.every((item, index, arr) => {
    console.log(item, index, arr)
    return item > 0
});
// 1 0 [1, 2, 3]
// 2 1 [1, 2, 3]
// 3 2 [1, 2, 3]
//原数组不变
arr; // [1, 2, 3]
arr1; //true

let arr2 = arr.every((item, index, arr) => {
    console.log(item, index, arr)
    return item > 1
})
// 1 0 [1, 2, 3]
//如果发现不符合条件的元素,立即返回 false,并且终止循环

arr2; // false

let arr3 = [].every((item, index, arr) => {
    console.log(item, index, arr)
    return item > 1
});
// 若传入一个空数组,无论如何都会返回true
arr3; // true

注意

a.如果是空数组,则返回true

15、some()方法测试是否至少有一个元素可以通过被提供的函数方法。返回一个布尔值

arrayObject.some(func(currentValue, index, array), thisArg)

let arr = [1, 2, 3];

let arr1 = arr.some((item, index, arr) => {
    console.log(item, index, arr)
    return item > 0
});
// 1 0 [1, 2, 3]
//原数组不变
//如果发现符合条件的元素,返回true,并且终止循环
arr; // [1, 2, 3]
arr1; //true

let arr2 = arr.some((item, index, arr) => {
    console.log(item, index, arr)
    return item > 3
})
// 1 0 [1, 2, 3]
// 2 1 [1, 2, 3]
// 3 2 [1, 2, 3]
arr2; // false

let arr3 = [].some((item, index, arr) => {
    console.log(item, index, arr)
    return item > 1
});
// 若传入一个空数组,则返回false
arr3; // false

注意

a.如果是空数组,则返回false

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

arr.reduce(func(accumulator, currentValue, index, array), initialValue)

let sum = [0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, index, array){
  return accumulator + currentValue;
});
sum; // 10

执行过程如下

callbackaccumulatorcurrentValueindexarrayreturn value
first call011[0, 1, 2, 3, 4]1
second call122[0, 1, 2, 3, 4]3
third call333[0, 1, 2, 3, 4]6
fourth call644[0, 1, 2, 3, 4]10

 

 

 

 

 

 

 

let sum = [0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, index, array){
  return accumulator + currentValue;
}, 20);
sum; // 30
callbackaccumulatorcurrentValueindexarrayreturn value
first call2000[0, 1, 2, 3, 4]20
second call2011[0, 1, 2, 3, 4]21
third call2122[0, 1, 2, 3, 4]23
fourth call2333[0, 1, 2, 3, 4]26
fifth call2644[0, 1, 2, 3, 4]30

 

 

 

 

 

 

 

 

结论,

如果没有提供初始值initialValue,reduce调用callback方法从索引1开始,累计器accumulator取数组第一个值,currentValue取数组第二个值。如果提供initialValue,从索引0开始,accumulator取initialValue, currentValue取数组第一个值。

[].reduce(function(acc, val, index, array){
    console.log(acc, val, index, array)
}); 
//TypeError: Reduce of empty array with no initial value
// 当没有初始值并且为空数组时,会报错

let sum = [1].reduce(function(acc, val, index, array){
    console.log(acc, val, index, array)
});

sum; //1 

let sum1 = [0].reduce(function(acc, val, index, array){
    console.log(acc, val, index, array)
}, 2);

sum1; // 2

//如果数组仅有一个元素(无论位置如何)并且没有提供initialValue, 或者有提供initialValue但是数组
//为空,那么此唯一值将被返回并且callback不会被执行

结论;

当没有初始值并且为空数组时,会报错。

如果数组仅有一个元素(无论位置如何)并且没有提供initialValue, 或者有提供initialValue但是数组为空,那么此唯一值将被返回并且callback不会被执行。

提供初始值通常更安全,建议使用都提供initialValue。

//计算对象中的值
let initialValue = 0
let sum = [{x: 1}, {x:2}, {x:3}].reduce(function (accumulator, currentValue) {
    return accumulator + currentValue.x;
},initialValue);

sum; // 6

注意:累加对象数组中包含的值,必须提供初始值,以便各个item正确通过函数

17、reduceRight() 方法和reduce()方法功能一样,不同的是执行顺序从右到左,即从数组的末尾向前。

arr.reduceRight(func(accumulator, currentValue, index, array), initialValue)

let sum = [0, 1, 2, 3, 4].reduceRight(function(accumulator, currentValue, index, array){
  return accumulator + currentValue;
});
sum; // 10

执行过程如下

callbackaccumulatorcurrentValueindexarrayreturn value
first call433[0, 1, 2, 3, 4]7
second call722[0, 1, 2, 3, 4]9
third call911[0, 1, 2, 3, 4]10
fourth call1000[0, 1, 2, 3, 4]10

 

 

 

 

 

 

let sum = [0, 1, 2, 3, 4].reduceRight(function(accumulator, currentValue, index, array){
  return accumulator + currentValue;
}, 10);
sum; // 20

执行过程如下

callbackaccumulatorcurrentValueindexarrayreturn value
first call1044[0, 1, 2, 3, 4]14
second call1433[0, 1, 2, 3, 4]17
third call1722[0, 1, 2, 3, 4]19
fourth call1911[0, 1, 2, 3, 4]20
fifth call2000[0, 1, 2, 3, 4]20

 

 

 

 

 

 

 

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

arr.indexOf(searchElement[, index]);

var arr = [1, 2, 3, 2, 1];

arr.indexOf(1); // 0

//默认从数组索引0开始查找

arr.indexOf(1, 2); // 4

//从数组索引2开始查找

arr.indexOf(1, 5); // -1

//index值超过或等于数组长度,即没有返回-1

arr.indexOf(1, -2); // 4

//从数组倒数第二个位置开始从左往右查找,

arr.indexOf(4); // -1

注意:

1、indexOf()查找顺序从左往右,即使index为负数,依旧如此。

2、index开始查找的位置。参数可选,默认为0,如果为负数,表示倒数第index个开始,查找。

3、如果index大于或等于数组长度,意味着不在数组里面查找,返回-1。

19、lastIndexOf() 和indexOf()方法一致,不同的是从查找顺序从后往前查找。

arr.lastIndexOf(searchElement[, index])

var arr = [1, 2, 3, 2, 1];

arr.lastIndexOf(1); // 4

//从数组末尾向前查找,index值默认为arr.length - 1, 即整个数组都被查找

arr.lastIndexOf(1, 1); // 0

//从数组索引1的位置开始,向前查找

arr.lastIndexOf(1, -1); //4

//从数组倒数第一个位置开始从后往前查找

arr.lastIndexOf(1, -6); // -1

//index为负数时,它的绝对值大于数组长度,数组不会被查找,返回-1

注意

1、index,开始查找位置,从后往前查找。参数可选,默认为数组的长度减一。

2、当index为负数时,它的绝对值大于数组长度时,数组不会被查找,返回-1。

20、Array.from()方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。es6

Array.from(arrayLike[, mapFun])

var arr = Array.from('love'); // ['l', 'o', 'v', 'e']

//从String生成数组

function fun(){
    return Array.from(arguments)
}
fun(1, 2, 3); // [1, 2, 3]

//从类数组对象生成数组

var ArrayLike = {'0':0, '1':1, '2':2, 'length': 3};

Array.from(ArrayLike, x => x + x); // [0, 2, 4]

//使用mapFun函数

var set = new Set(['a', 'b', 'c', 'a']);

Array.from(set); // ['a', 'b', 'c']

//从Set生成数组

var map = new Map([[1, 0], [2, 1], [3, 2]]);

Array.from(map.values()); // [0, 1, 2]

Array.from(map.keys()); // [1, 2, 3]

//从Map生成数组


注意

1、arraylike,想要转换成数组的伪数组对象或可迭代对象。

2、mapFun,可选参数,新数组中的每个元素会执行该回调函数。

21、Array.of()方法创建一个具有可变数量参数的新数组实例。es6

Array.of(x0, x1, x2...)

Array.of(5); // [5]

Array(5); // [empty × 5]

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

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

22、copyWithin()方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。es6

copyWithin(target,start,end)

tartget,为复制序列到该位置,如果为负数,则从末尾开始计算。

start,开始复制数组的起点,可选,默认为0。如果为负数,从末尾开始计算。

end,结束复制数组的位置,可选,默认为arr.length, 即复制至数组结尾,但不包含end这个位置的元素。

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

arr.copyWithin(1); // [1, 1, 2, 3, 4];

//start,end都未填写,即复制整个数组,粘贴到数组索引为target:1的位置

arr.copyWithin(0, 3, 4); // [4, 2, 3, 4, 5]

//start为3, end为4,即复制索引为3的元素4,粘贴到索引为0的位置

arr.copyWithin(-1, -3, -2); // [1, 2, 3, 4, 3]

//start为-3,end为-2,即复制倒数第三个元素3,粘贴到倒数第一的位置

arr.copyWithin(-1, -2, -3); // [1, 2, 3, 4, 5];

//如果start >= end,无法复制内容,即原数组不改变

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

arr.fill(value, start, end)

value:用于填充数组元素的值。

start:可选,开始索引,默认为0。

end:可选,终止索引,默认为arr.length,但不包含end索引。

Array(4).fill(1); // [1, 1, 1, 1]

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

arr.fill(5, 0, 2); // [5, 5, 3, 4]

arr; // [5, 5, 3, 4]

//不包含,end索引,原数组改变

arr.fill(2, -4, -5); // [1, 2, 3, 4]

//start >= end, 无法填充


注意

1、原数组改变,填充顺序从左往右,start需小于end,否则原数组不填充。

2、start,end为负数时候,从数组末尾开始,填充顺序不变。

24、find()方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。es6

arr.find(func(value, index, arr), thisArg)

var arr = [1, 2, 3];
var find = arr.find((val, index, arr) => {
    console.log(val, index, arr)
    return val > 2
});

//1 0 [1, 2, 3]
//2 1 [1, 2, 3]
//3 2 [1, 2, 3]

find;//3

var f = arr.find(val => val > 3);

f; //undefined

arr; // [1, 2, 3] 原数组不改变

注意

1、原数组不改变,当没有符合条件的值时返回undefined。

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

arr.findIndex(func(value, index, arr), thisArg)

var arr = [1, 2, 3];

var index = arr.findIndex((val, index, arr) => {
    console.log(val, index, arr)
    return val > 2
})

//1 0 [1, 2, 3]
//2 1 [1, 2, 3]
//3 2 [1, 2, 3]

index;//2  val大于2时的值为3, 索引是2

var i = arr.findIndex(val => val > 3);

i; //-1

arr; // [1, 2, 3] 原数组不改变

注意

1、原数组不改变,当没有符合条件的值时返回-1。

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

arr.entries()

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

var t = arr.entries();

t.next(); // {value: [0, 'a'], done: false}
t.next(); // {value: [1, 'b'], done: false}
t.next(); // {value: [2, 'c'], done: false}
t.next(); // {value: undefined, done: true}

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

27、values()keys() 方法返回一个新的Array Iterator 对象,分别是值和索引。es6

arr.values()和arr.keys()

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

var val = arr.values();

val.next(); // {value: 'a', done: false}
val.next(); // {value: 'b', done: false}
val.next(); // {value: 'c', done: false}
val.next(); // {value: undefined, done: true}

var key = arr.keys();

for(var i of key){
	console.log(i)
}

// 0
// 1
// 2

28、includes()方法返回一个布尔值,表示某个数组是否包含给定的值。ES2016

arr.includes(value[, index])

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

arr.includes('c'); // true
arr.includes('c', 3);   // false
arr.includes('b', -1); // false
arr.includes('b', -2); // true
//index如果是负数,从倒数开始,顺序不变,从左往右

[NaN].indexOf(NaN); // -1
[NaN].includes(NaN); // true

//可以看到indexOf无法判断NaN是否在数组中,includes可以

注意

1、index可选。默认为0,当大于等于数组长度时,返回false,且该数组不会被搜索。

2、index为负数时,从数组倒数开始,搜索顺序不变,即从左到右。

29、flat()方法会按照一个可指定的深度递归遍历数组,并且返回一个新一维数组,原数组不变。ES2019

arr.flat([depth])

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

arr.flat(); // [1, 2, 3, 4];
// 等效于
arr.reduce((acc, val) => acc.concat(val), []); // [1, 2, 3, 4]

arr; // [1, 2, [3, 4]] 原数组不变

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

arr.flat(); // [1, 2, 3, [4]] 只展开一层

arr.flat(2); // [1, 2, 3, 4];

//使用 Infinity,可展开任意深度的嵌套数组
var arr = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];

arr.flat(Infinity); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

//移除数组中的空项, 但原数组不变
var arr = [1, 2, , 3];

arr.flat(); // [1, 2, 3]

arr; // [1, 2, , 3]

注意

1、flat不会改变原数组,depth可选默认为1,展开任意深度使用Infinity。

30、flatMap()方法对原数组的每个成员执行一个函数,然后压缩成一个新数组。相当于执行一次map,再执行一次深度值为1的flat()。ES2019

arr.flatMap(func(value, index, arr), thisArg)

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

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

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

arr.flatMap(x => [[x * 2]]); // [[2], [4], [6], [8]]
//只能展开一层

31、toString()返回一个字符串,表示指定的数组及其元素。

arr.toString()

var arr = [1, 2, 3];

arr.toString(); // "1,2,3"

arr + ''; // "1,2,3"

//当一个数组被作为文本值或者进行字符串连接操作时,将会自动调用其 toString 方法

最后这些是我查阅资料整理出来的数组方法,若有不对的地方,欢迎私信或评论,一起学习进步。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值