不改变原数组的方法
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]
总结
- 第一个参数是开始被替换的元素位置
- 要替换数据的位置范围:从第二个参数是开始读取的元素,在
第三个参数前面一个元素
停止读取 - 数组的长度不会改变
- 读了几个元素就从开始被替换的地方替换几个元素
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了一个值。
适用规则
- 对于空数组是不会执行回调函数的
- 对于已在迭代过程中删除的元素,或者空元素会跳过回调函数
- 遍历次数再第一次循环前就会确定,再添加到数组中的元素不会被遍历。
- 如果已经存在的值被改变,则传递给 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
,而undefined
和null
会被处理成空字符串。
// 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]