Javascript 数组常用方法

不改变原数组的方法

join

将一个数组的所有元素连接成一个字符串并返回这个字符串。
返回值:返回连接后的新数组

语法

Array.join()

参数

第一个参数(可选):指定的分隔符(如果省略该参数,则使用逗号作为分隔符)

示例代码

//如果数组只有一个元素,那么将返回该元素,而不使用分隔符。
const myArr = ['one']
console.log(myArr .join())   // one

const arr = [1, 2, 3]
// 如果不传,默认数组元素用逗号(,)分隔
console.log(arr.join())   // 1,2,3
// 如果是空字符串(""),则所有元素之间都没有任何字符。
console.log(arr.join(''))   // 123
// 指定一个字符串来分隔数组的每个元素
console.log(arr.join('+'))   // 1+2+3

concat

用于连接两个或多个数组。
返回值:返回连接后的新数组

语法

Array.concat()

参数

参数(必选):可以是具体的值,也可以是数组对象。可以是任意多个

示例代码

const arr = [1, 2, 3]
const newArr = arr.concat()
// 如果省略参数,则concat会返回当前数组的浅拷贝。
console.log(newArr)   // [1,2,3]
console.log(newArr === arr)   // false

// 如果传入的不是数组,则直接把参数添加到数组后面,
// 如果传入的是数组,则将数组中的各个项添加到数组中。
const arr = [1, 2, 3]
const newArr = arr.concat(4,[5, 6])
console.log(newArr)   // [1, 2, 3, 4, 5, 6]

// 如果传入一个二维数组
const newArr2 = arr.concat([4,[5,6]]) 
console.log(newArr2)   // [1, 2, 3, 4, Array(2)]
console.log(newArr2[4]) // [5,6]

slice

返回从原数组中截取指定开始下标到结束下标(不包含结束end)之间的项组成的新数组。组成的新数组的一部分浅拷贝到一个新数组对象。
返回值:返回一个新数组

语法

Array.slice(start, end)

参数

参数1(可选):起始索引 start(接受负值,默认从 0 开始),从该索引开始提取原数组元素。
参数2(可选):结束索引(不包括) end 在该索引结束提取原数组元素。如果该参数省略,则一直提取到原数组末尾结束(包括最后一个元素)。

示例代码

const arr = [1, 2, 3, 4]
const newArr = arr.slice(1)
console.log(newArr);   // [2,3,4]
const newArr1 = arr.slice(1, 3)
console.log(newArr1)   // [2,3]
const newArr2 = arr.slice(-3, -1)
console.log(newArr2)   // [2,3]

// 如果结束位置小于起始位置,则返回空数组
const arr = [1, 2, 3, 4]
const newArr = arr.slice(2, 1)
console.log(newArr)   // []

indexOf

返回在数组中找到第一次出现指定元素的索引(从数组的开头开始向后查找)。如果不存在,则返回-1。
返回值:第一次查到的索引,未找到返回-1

语法

Array.indexOf(item, start)

参数

参数1(必选):被查找的元素
参数2(可选):开始查找的位置(不能大于等于数组的长度,返回-1),接受负值,默认值为0。

注意

1、indexOf()它内部使用严格相等运算符(===)进行判断,这会导致对NaN的误判。不能识别NaN。
2、indexOf() 方法使用严格相等来检查元素是否存在,这意味着值以及数据类型应该相同。

示例代码

const arr=['啦啦',1,2,3,4,5,2,NaN]
console.log(arr.indexOf(2));   // 2
console.log(arr.indexOf('啦'));   // -1 
console.log(arr.indexOf('NaN'));   // -1 
console.log(arr.indexOf('啦啦'));   // 0
console.log(arr.indexOf(2,3));   // 6

lastIndexOf

返回要查找的元素在数组中的位置(从数组的末尾开始向前查找)。如果不存在,则返回-1。
返回值:第一次查到的索引,未找到返回-1

语法

Array.lastIndexOf(searchElement,fromIndex)

参数

参数1(必选):被查找的元素
参数2(可选):从此位置开始逆向查找,默认为数组的长度减 1 (arr.length - 1)。

示例代码

const arr=['啦啦',1,2,3,4,5,2,NaN]
console.log(arr.lastIndexOf(2));   // 6
console.log(arr.lastIndexOf('啦'));   // -1 
console.log(arr.lastIndexOf('NaN'));   // -1 
console.log(arr.lastIndexOf('啦啦'));   // 0
console.log(arr.lastIndexOf(2,3));   // 2

includes (ES6新增)

判断一个数组是否包含一个指定的值。
返回值:布尔值

  • 为了弥补indexOf方法的缺陷而出现的
    • 它内部使用严格相等运算符(===)进行判断,这会导致对NaN的误判。
    • indexOf方法检查是否包含某个值不够语义化,需要判断是否不等于-1,表达不够直观

语法

array.includes(element, start)

参数

参数1(必选):要搜索的元素。
参数2(可选):默认 0。在数组中的哪个位置开始搜索。

示例代码

const arr = ['a','b','c','d']; 
console.log(arr.includes('c'));   // true
console.log(arr.includes(2));   // false

const arr2 = ["Banana", "Orange", "Apple", "Mango"];
console.log(arr2.includes("Banana", 3));   // false

toLocaleString 数组转字符串

返回一个表示数组元素的字符串。该字符串由数组中的每个元素的 toLocaleString() 返回值经调用 join() 方法连接(由逗号隔开)组成。

语法

Array.toLocaleString()

参数

示例代码

const array = [1, 'a', { id: 1 }]
// 数组中的每个元素都会调用自身的toLocaleString方法,对象调用对象的toLocaleString
console.log(array.toLocaleString())   // 1,a,[object Object]

const array1 = [22, 33, 44, 55];
const str = array1.toLocaleString();
console.log(str);   // 22, 33, 44, 55

toString 数组转字符串

把数组转换为由逗号链接起来的字符串
该方法的效果和join方法一样,都是用于数组转字符串的,但是与join方法相比没有优势,也不能自定义字符串的分隔符,因此不推荐使用。

语法

Array.toLocaleString()

参数

示例

const a = [ 'toString','示例'].toString();
console.log(a)   // toString,示例
const b = ['toString','示例']+'啦啦啦';
// 当数组和字符串操作的时候,js 会调用这个方法将数组自动转换成字符串
console.log(b)   // toString,示例啦啦啦

改变数组的方法

pop

删除数组的最后一个元素,并返回这个元素(即被删除的元素)。
返回值:被删除的元素

语法

Array.pop()

参数

示例

const arr = ['a', 'b', 'c']
console.log(arr.pop())   // c
console.log(arr);   // ["a", "b"]
// 如果数组为空,则不改变数组,返回 undefined;
const arr1 = [];
console.log(arr1.pop());   // undefined
console.log(arr1); // []

push

向数组末尾添加新项,并返回新长度。
返回值:新增后数组的长度

语法

Array.push()

参数

参数(必选):要添加到数组中的项。传递多个用逗号隔开,任何数据类型都可以

示例

const arr = ['a', 'b', 'c']
// 直接打印是返回新增后数组的长度
console.log(arr.push('d'))   // 4

// arr.push('e','f')
// 先push再打印是返回新数组
// console.log(arr)   // ['a', 'b', 'c', 'd', 'e', 'f']

shift

删除数组的第一个元素,并返回这个元素(即被删除的元素)。
返回值:被删除的项
是否改变原数组:改变

语法

Array.shift()

参数

示例

const arr = ['a', 'b', 'c']
console.log(arr.shift())   // a
console.log(arr)   // ['b', 'c'

unshift

将新项添加到数组的开头,并返回新的长度。
返回值:新数组的长度

语法

Array.unshift()

参数

参数(必选):要添加到数组开头的项。传递多个用逗号隔开,任何数据类型都可以

示例

const arr = ['c','d'];
arr.unshift('a','b');
console.log(arr);   // ["a", "b", "c", "d"]

reverse

反转数组中元素的顺序。
返回值:倒序后新数组

语法

Array.reverse()

参数

示例

const arr = [6,8,10,12]; 
console.log(arr .reverse());   // [12, 10, 8, 6]

sort

对数组的项进行排序。(默认是从小到大升序来排序 并且是根据字符串来排序的)
返回值:排序后新数组

语法

Array.sort()

参数

参数(可选):规定排序规则。默认是按字母和升序将值作为字符串进行排序。

示例

// sort在不传递参数情况下,只能处理10以内(个位数)数字排序。
// 处理大于10数字排序
const points = [40, 100, 11, 59, 25, 10];
points.sort(function(a, b){return a-b});   // 升序
// points.sort(function(a, b){return b-a});   // 降序
console.log(points);   // [10, 11, 25, 40, 59, 100]
// 处理字符排序
const fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();
console.log(fruits);   // ['Apple', 'Banana', 'Mango', 'Orange']

splice

向数组中添加/删除项目,然后返回被删除项目。
返回值:删除后的新数组

语法

Array.splice (index, howmany, item1, 。。。, itemX))

参数

参数1(必选):整数,要添加/删除的元素开始索引,使用负值指定从数组末尾开始的位置。
参数2(可选):要删除的个数。如果设置为 0,则不会删除任何元素。
参数3(可选):要添加到数组中的元素。

示例

// 增加
// arr1.splice(n,0,m)从索引n开始删除0项,把m或者更多的内容插入到索引n的前面
const arr1 = [33,44,55,66,77,88];
arr1.splice(2,0,'a','b')
console.log(arr1);   // [33, 44, 'a', 'b', 55, 66, 77, 88]

// 修改
// arr2.splice(n,x,m)从索引n开始删除x个,m替换删除的部分
const arr2 = [33,44,55,66,77,88];
arr2.splice(1,2,'x','y')
console.log(arr2);   // [33, "x", "y", 66, 77, 88]

// 删除
// arr3.splice(n,m) 从索引n开始删除m个内容。
const arr3 = [33,44,55,66,77,88];
// 返回删除的新数组,原有数组改变
// console.log(arr3.splice(3,2))   // [66, 77]
// 如果第二个参数省略,则从n删除到末尾
console.log(arr3.splice(3));   // [66, 77, 88]

copyWithin (ES6新增)

将数组元素复制到数组中的另一个位置,覆盖现有值。
返回值:被改变后的数组

语法

Array.copyWithin(target, start, end)

参数

参数1(必选):将元素复制到的索引位置。如果为负值,表示倒数。
参数2(可选):开始复制元素的索引位置(默认为 0)。如果为负值,表示倒数。
参数3(可选):停止复制元素的索引位置(不包含自身),默认为数组的长度。使用负数可从数组结尾处规定位置。

示例

const arr1 = [1, 2, 3, 4]
console.log(arr1.copyWithin(2,0));   // [1,2,1,2]
// 将数组的前两个元素替换数组的最后两个位置:
// 从索引2的位置开始替换
// 从索引0的位置开始复制数据

const arr2 = [{id: 1},{id: 2},{id: 3}]
console.log(arr2.copyWithin(0, 2))   // [{id: 3},{id: 2},{id: 3}]

// 从索引2的位置开始替换
// 从索引0的位置开始复制
// 在遇到索引1的时候停止复制(不包含自身)
[1, 2, 3, 4].copyWithin(2,0,1)   // [1,2,1,4]

总结

  1. 第一个参数是开始被替换的元素位置
  2. 要替换数据的位置范围:从第二个参数是开始读取的元素,在第三个参数前面一个元素停止读取
  3. 数组的长度不会改变
  4. 读了几个元素就从开始被替换的地方替换几个元素

fill (ES6新增)

使用给定值,填充一个数组。
返回值:填充后的新数组

语法

Array.fill(value, start, end)

参数

  • 参数1(必选):用于填充数组的值。
  • 参数2(可选):开始填充数组的索引(默认为 0)。
  • 参数3(可选):停止填充数组的索引,默认为数组的长度。填充的元素不包括终止的索引元素

示例代码

// 当传入一个参数的时候,会用这个参数的值填充整个数组
const arr = [{ id: 1 }, { id: 2 }, { id: 3 }]
console.log(arr.fill({ id: 4 }))   // [{ id: 4 }, { id: 4 }, { id: 4 }]

// 当传入多个个参数的时候,用这个参数的值填充部分数组
const arr1 = [{ id: 1 }, { id: 2 }, { id: 3 }]
// 从数组下标索引为1的元素开始填充
console.log(arr1.fill({ id: 4 }, 1))   // [{ id: 1 }, { id: 4 }, { id: 4 }]

// 填充的元素不包括终止的索引元素。
const arr2 = [1, 2, 3, 4]
console.log(arr2 .fill(0, 1, 2))   // [1, 0, 3, 4]

遍历方法

js中遍历数组并不会改变原始数组的方法总共有12个:

ES5:forEach、every 、some、 filter、map、reduce、reduceRight、
ES6:find、findIndex、keys、values、entries

关于遍历
  • 尽量不要在遍历的时候,修改后面要遍历的值
  • 尽量不要在遍历的时候修改数组的长度(删除/添加)

forEach

对数组中的每个项目执行一个函数。循环遍历数组每一项。

语法

Array.forEach(function(currentValue, index, arr), thisValue)

参数

  • 参数1(必选):callback生成新数组元素的函数。该函数接收三个参数
    • currentValue:当前元素
    • index(可选):当前元素的索引
    • arr(可选):数组本身
  • 参数2(可选):当执行回调函数时用作 this 的值。默认值为undefined

示例代码

const arr = [1, 2, 3, 4];
const copy = [];
arr.forEach(i => {
    copy.push(i * 2);
});
console.log(copy); // [ 2, 4, 6, 8 ]
console.log(arr); // [ 1, 2, 3, 4 ]

let a = [1, 2, ,3]; // 最后第二个元素是空的,不会遍历(undefined、null会遍历)
let obj = { name: 'OBKoro1' };
let result = a.forEach(function (value, index, array) { 
	a[3] = '改变元素';
	a.push('添加到尾端,不会被遍历')
	console.log(value, 'forEach传递的第一个参数'); // 分别打印 1 ,2 ,改变元素
	console.log(this.name); // OBKoro1 打印三次 this绑定在obj对象上
	// break; // break会报错
	return value; // return只能结束本次回调 会执行下次回调
	console.log('不会执行,因为return 会执行下一次循环回调')
}, obj);
console.log(result); // 即使return了一个值,也还是返回undefined
// 回调函数也接受接头函数写法

// 1 'forEach传递的第一个参数'
// OBKoro1
// 2 'forEach传递的第一个参数'
// OBKoro1
// 改变元素 forEach传递的第一个参数
// OBKoro1
// undefined

注意

  • 无法中途退出循环,只能用return退出本次回调,进行下一次回调。
  • 它总是返回 undefined值,即使你return了一个值。

适用规则

  1. 对于空数组是不会执行回调函数的
  2. 对于已在迭代过程中删除的元素,或者空元素会跳过回调函数
  3. 遍历次数再第一次循环前就会确定,再添加到数组中的元素不会被遍历。
  4. 如果已经存在的值被改变,则传递给 callback 的值是遍历到他们那一刻的值。

map

返回一个新数组,结果是该数组中的每个元素都调用提供的函数后返回的结果
按照某种映射关系, 把数组的每一个元素给修改了

  • 如果没有return, 则map的返回值都是undefined

语法

Array.map(function(currentValue, index, arr), thisArg)

参数

同forEach

示例代码

const arr = [2,4,5,7,9,12,14];
const doubleArr = arr.map(function(item){
	return item * 2;
});
console.log(doubleArr);   // [4, 8, 10, 14, 18, 24, 28]
// 原数组不变
console.log(arr);   // [2, 4, 5, 7, 9, 12, 14]

every

检测数所有元素是否都符合指定条件

  • 如果数组中检测到有一个元素不满足,则整个表达式返回 false,且剩余的元素不会再进行检测
  • 如果所有元素都满足条件,则返回 true

语法

Array.map(function(currentValue, index, arr), thisArg)

参数

同forEach

示例代码

const arr = [1, 2, 3, 4];
console.log(arr.every(i => i > 2));   // false
console.log(arr.every(i => i > 0));   // true
// 不对没有值的数组元素执行函数,执行结果都为true
console.log([].every(() => {}));   // true
console.log([].every(i => i === 'pr'));   // true
// 原数组不变
console.log(arr);   // [ 1, 2, 3, 4 ]

some

判断数组中是否存在满足条件的元素。

  • 如果有一项满足条件,则表达式返回 true。且剩余的元素不会再进行检测
  • 如果没有满足条件的元素,则返回 false;

语法

Array.some(function(currentValue, index, arr), thisArg)

参数

同forEach

示例代码

const arr = [12,23,-24,42,1];
const result = arr.some(function(item, index){
  return item < 0
})
console.log(result)   // true

filter

创建一个新的数组,新数组中的元素是通过检查符合条件的所有元素。

语法

Array.filter(function(currentValue, index, arr), thisArg)

参数

同forEach

示例代码

const arr = [32, 33, 16, 40];
const result = arr.filter(function (value, index, array) {
	return value >= 18; // 返回arr数组中所有大于18的元素
});
console.log(result)   // [32, 33, 40]
// 不对没有值的数组元素执行函数,执行结果都为[]
console.log([].filter(() => {}));   // []
console.log([].filter(i => i === 'pr'));   // []
// 原数组不变
console.log(arr)   // [32, 33, 16, 40]

reduce

从数组的第一项开始,迭代数组的所有元素,构建一个最终返回的值,返回函数累计处理的结果。
累加器的值在所有迭代中都会被记住,并最终在最后一次迭代后返回。

语法

array.reduce(function(prev, cur, Index, arr), initialValue)

参数

  • 参数1(必选):callback执行数组中每个值的函数。该函数接收四个参数
    • prev(必选):初始值, 或者上一次调用回调函数返回的值
    • cur(必选):当前元素的值
    • index(可选):当前元素的索引值
    • arr(可选):数组对象本身
  • 参数2(可选):作为初始值传递给函数的值
    • 如果没有提供初始值,则将使用数组中的第一个元素。
    • 在没有初始值的空数组上调用reduce将报错。

示例代码

const values = [5, 6, 7, 8, 9]
// 从数组的第一项开始,逐个遍历到最后。
const sum = values.reduce((prev, cur, Index, arr) => {
	return prev+ cur
})
console.log(sum)   // 35

// 在没有初始值的空数组上调用reduce将报错。
// Uncaught TypeError: Reduce of empty array with no initial value
[].reduce(() => {})

// 这个函数返回的任何值都会作为第一个参数自动传给下一项。
const arr1 = ['L', 'O', 'V', 'E'].reduce((prev, cur) => {
  console.log('prev: ', prev)
  console.log('cur: ', cur)
  return prev + cur
})
// 最后一次 retrun 的结果
console.log(arr1)   // LOVE
/* 
prev:  L
cur:  O
prev:  LO
cur:  V
prev:  LOV
cur:  E
LOVE
*/

const numbers = [15.5, 2.3, 1.1, 4.7];
const sum = numbers.reduce((prev, cur, Index, arr) => {
	return prev + Math.round(cur);
},0)
console.log(sum)   // 24

reduceRight

reduceRight()reduce()作用类似,使用reduce()还是reduceRight(),主要取决于要从哪头开始遍历数组。除此之外,它们完全相同。

示例代码

const values = [1,2,3,4,5]
// 从数组的最后一项开始,向前遍历到第一项。
const sum = values.reduceRight(function(prev, cur, index, array){
  return prev + cur
});
console.log(sum)   // 15

find

返回数组中匹配的第一个元素的值,

  • 如果找到函数返回 true 值的数组元素,则 find() 返回该数组元素的值(并且不检查剩余值)
  • 否则返回undefined。
  • 不对空数组执行该函数。

语法

Array.find(function(element, index, arr), thisValue)

参数

  • 参数1(必选):callback执行数组中每个值的函数。该函数接收四个参数
    • element(必选):当前元素
    • index(可选):当前元素的索引值
    • arr(可选):数组对象本身
  • 参数2(可选):当执行回调函数时 this 的值。

示例代码

const arr = [5, 12, 8, 130, 44];
const res = arr.find(item => item > 10);
console.log(res);   // 12
console.log(arr.find(item => item < 0));   // undefined

const arr2 = [5, 12, 8, 130, 44, NaN];
const res2 = arr2.find((n) => Object.is(NaN, n));
console.log(res2);   // NaN

findIndex

返回第一个符合条件的数组成员(引用类型)的位置(下标),如果所有成员都不符合条件,则返回-1。

语法

Array.findIndex(function(element, index, arr), thisValue)

参数

同find()

示例代码

const arr = [5, 12, 8, 130, 44]
const res = arr.findIndex(item => item > 10);
console.log(res);   // 1
console.log(arr.findIndex(item => item < 0));   // -1

const arr2 = [5, 12, 8, 130, 44, NaN];
const res2 = arr2.findIndex((n) => Object.is(NaN, n));
console.log(res2);   // 5

find和findIndex这两个方法都可以识别NaN,弥补了indexOf的不足.

entries()、keys()、values() ES6新增

用于遍历数组,它们都返回一个遍历器(Array Iterator)对象。可以用for…of循环进行遍历,
他们的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()键值对的遍历

语法

Array.keys()
Array.values()
Array.entries()

参数

示例代码

let arr = ['a', 'b']
for (let index of arr.keys()) {
  console.log(index);
}
// 0
// 1

for (let elem of arr.values()) {
  console.log(elem);
}
// a
// b

for (let [index, elem] of arr.entries()) {
  console.log(`${index}-${elem}`);
}
// 0-a
// 1-b

// 在for..of中如果遍历中途要退出,可以使用break退出循环。

// 如果不使用for...of循环,可以手动调用遍历器对象的next方法,进行遍历。
let letter = ['a', 'b', 'c'];
let entries = letter.entries();
console.log(entries.next().value); // [0, 'a']
console.log(entries.next().value); // [1, 'b']
console.log(entries.next().value); // [2, 'c']

ES6中数组的拓展

flat

将嵌套的数组“拉平”,变成一维的数组。

语法

Array.flat()

参数

参数1(可选):指定要提取嵌套数组的结构深度,默认值为 1

示例代码

// 默认只拉一层
[1, 2, [3, [4, 5]]].flat()   // [1, 2, 3, [4, 5]]

// 拉平多层的嵌套数组
// flat()的参数为2,表示要“拉平”两层的嵌套数组。
[1, 2, [3, [4, 5]]].flat(2)   // [1, 2, 3, 4, 5]

// 如果不管有多少层嵌套,都要转成一维数组,可以用Infinity关键字作为参数。
[1, [2, [3]]].flat(Infinity)   // [1, 2, 3]

// 如果原数组有空位,flat()方法会跳过空位。
[1, 2, , 4, 5].flat()   // [1, 2, 4, 5]

flatMap

对原数组的每个成员执行一个函数,然后对返回值组成的数组执行flat()方法。

语法

Array.flatMap(function(element, index, arr), thisValue)

参数

  • 参数1(必选):callback遍历函数。该函数接收四个参数
    • element(必选):当前元素
    • index(可选):当前元素的索引值
    • arr(可选):数组对象本身
  • 参数2(可选):当执行回调函数时 this 的值。

示例代码

// 相当于 [[2, 4], [3, 6], [4, 8]].flat()
// flatMap()只能展开一层数组。
[2, 3, 4].flatMap((x) => [x, x * 2])   // [2, 4, 3, 6, 4, 8]

// 相当于 [[[2]], [[4]], [[6]], [[8]]].flat()
[1, 2, 3, 4].flatMap(x => [[x * 2]])   // [[2], [4], [6], [8]]
// 遍历函数返回的是一个双层的数组,但是默认只能展开一层,因此flatMap()返回的还是一个嵌套数组。

at

JavaScript 不支持数组的负索引,如果要引用数组的最后一个成员,不能写成arr[-1],只能使用arr[arr.length - 1]。为了解决负索引这个问题,es6中为数组实例增加了at()方法,接受一个整数作为参数。

  • 返回对应下标的值,支持负索引。
  • 如果参数位置超出了数组范围,at()返回undefined
  • 这个方法不仅可用于数组, 也可用于字符串和类型数组( TypedArray)

语法

Array.at()

参数

参数:一个整数

示例代码

const arr = [5, 12, 8, 130, 44];
console.log(arr.at(2))   // 8
console.log(arr.at(-2))   // 130
console.log(arr.at(-6))   // undefined

const sentence = 'This is a sample sentence';
console.log(sentence.at(0))   // 'T'
console.log(sentence.at(-1))   // 'e'
console.log(sentence.at(-100))   // undefined
console.log(sentence.at(100))   // undefined

form

将一个类似数组的对象转为真正的数组。
返回值:返回一个新数组

  • 这个类似数组的对象必须要有length属性才可以,转为数组。否则将会转为为一个空数组

语法

Array.from(arraylLike, MapFn, thisArg)

参数

参数1:一个类似数组的对象or可迭代对象
参数2(可选):新数组中的每一个元素执行该回调函数
参数3(可选):执行回调函数MapFn时的this对象

示例代码

let arrayLike = {
  '0': 'a',
  '1': 'b',
  '2': 'c',
  length: 3
};

// ES5的写法
let arr1 = [].slice.call(arrayLike)
console.log(arr1)   // ['a', 'b', 'c']

// ES6的写法
let arr2 = Array.from(arrayLike)
console.log(arr2)   // ['a', 'b', 'c']

// 当没有类似数组的对象没有length属性
let arrayLike2 = {
  '0': 'a',
  '1': 'b',
  '2': 'c',
};
//此时返回的是一个空数组
console.log(Array2.from(arrayLike2)); // []

console.log(Array.from('hello'))   // ['h','e','l','l','o']
console.log(Array.from(new Set(['a','b'])))   // ['a','b']

of

将【一组数值】转换为数组.

  • 这个方法的主要目的,是弥补数组构造函数Array()的不足。因为参数个数的不同,会导致Array()的行为有差异。
  • Array.of()基本上可以用来替代Array()或new Array(),并且不存在由于参数不同而导致的重载。它的行为非常统一。

语法

Array.of()

参数

参数(可选):一个或者多个值。如果没有参数,就返回一个空数组。

示例代码

const a = Array.of(10, 20, 26, 38);
console.log(a);   // [10, 20, 26, 38]

const b = Array.of(1).length;
console.log(b);   // 1

const c = Array.of(3)
console.log(c);   // [3]

// Array.of()可以用以下的代码模拟实现:
function ArrayOf() {
  return [].slice.call(arguments);
}

// 数组构造函数Array()的不足。因为参数个数的不同,会导致Array()的行为有差异。
Array()   // []
Array(3)   // [, , ,]
Array(3, 11, 8)   // [3, 11, 8]

// Array.of()基本上可以用来替代Array()或new Array(),并且不存在由于参数不同而导致的重载。它的行为非常统一。
Array.of()   // []
Array.of(undefined)   // [undefined]
Array.of(1)   // [1]
Array.of(1, 2)   // [1, 2]

扩展运算符

将一个数组转为用逗号分隔的参数序列。

  • 只有函数调用时,扩展运算符才可以放在圆括号中,否则会报错。

示例代码

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

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

[...document.querySelectorAll('div')]   // [<div>, <div>, <div>]

// 扩展运算符与正常的函数参数可以结合使用,非常灵活。
function f(v, w, x, y, z) { }
const args = [0, 1];
f(-1, ...args, 2, ...[3]);

// 扩展运算符后面还可以放置表达式。
const arr = [
  ...(x > 0 ? ['a'] : []),
  'b',
];

// 如果扩展运算符后面是一个空数组,则不产生任何效果。
console.log([...[], 1])   // [1]

// 只有函数调用时,扩展运算符才可以放在圆括号中,否则会报错。
(...[1, 2])
// Uncaught SyntaxError: Unexpected token '...'

console.log((...[1, 2]))
// Uncaught SyntaxError: Unexpected token '...'

console.log(...[1, 2])   // 1 2
// 上面三种情况,扩展运算符都放在圆括号里面,但是前两种情况会报错,因为扩展运算符所在的括号不是函数调用。

数组的空位

数组的某一个位置没有任何值.

比如Array()构造函数返回的数组都是空位。

const arr = new Array(3)
console.log(arr); // [, , ,] 谷歌浏览器中会有出现  [空属性 × 3]
//上面代码中,Array(3)返回一个具有 3 个空位的数组。

注意

空位不是undefined,某一个位置的值等于undefined,依然是有值的。空位是没有任何值

空位的处理

ES5:对空位的处理,已经很不一致了,大多数情况下会忽略空位。
  • forEach(), filter(), reduce(), every() some()都会跳过空位。
  • map()会跳过空位,但会保留这个值
  • join()toString()会将空位视为undefined,而undefinednull会被处理成空字符串。
// forEach方法
[,'a'].forEach((x,i) => console.log(i)); // 1

// filter方法
['a',,'b'].filter(x => true) // ['a','b']

// every方法
[,'a'].every(x => x==='a') // true

// reduce方法
[1,,2].reduce((x,y) => x+y) // 3

// some方法
[,'a'].some(x => x !== 'a') // false

// map方法
[,'a'].map(x => 1) // [,1]

// join方法
[,'a',undefined,null].join('#') // "#a##"

// toString方法
[,'a',undefined,null].toString() // ",a,,"
ES6:则是明确将空位转为undefined。
let arr = new Array(3)
console.log(arr[0] === undefined); //true
  • Array.from()方法会将数组的空位,转为undefined,也就是说,这个方法不会忽略空位。
  • 扩展运算符(…)也会将空位转为undefined。
  • entries()、keys()、values()、find()和findIndex()会将空位处理成undefined。
Array.from(['a',,'b'])   // [ "a", undefined, "b" ]

[...['a',,'b']]   // [ "a", undefined, "b" ]

// entries()
[...[,'a'].entries()]   // [[0,undefined], [1,"a"]]

// keys()
[...[,'a'].keys()]   // [0,1]

// values()
[...[,'a'].values()]   // [undefined,"a"]

// find()
[,'a'].find(x => true)   // undefined

// findIndex()
[,'a'].findIndex(x => true) // 0
  • copyWithin()会连空位一起拷贝。
[,'a','b',,].copyWithin(2,0)   // [,"a",,"a"]
  • fill()会将空位视为正常的数组位置。
new Array(3).fill('a')   // ["a","a","a"]
  • for…of循环也会遍历空位。
let arr = [, ,];
for (let i of arr) {
  console.log(1);
}
// 1
// 1
  • map()方法遍历,空位是会跳过的
let arr = [, ,];
const newArr = arr.map((el,index,arr) => {
  return 1
});
console.log(newArr)
// [空属性 × 2]

参考文章:
【干货】js 数组详细操作方法及解析合集
数组的扩展
ES6中数组新增的方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值