一、ES5 中数组遍历有多少种方法?它们有什么优势和缺点?
1、for 循环 - 支持 break 和 continue
2、forEach - ES5 新增 不支持 break 和 continue
3、every - ES5 新增 是否继续遍历取决于函数返回值,默认返回 false,return true 会使循环继续
4、for in - ES5 新增 为 object 遍历 支持 break 和 continue,for in 可以遍历数组的两个因素:1、数组是对象 2、数组是可遍历的
5、for of - 遍历 ES6 自定义数据(类型)对象
// 方法一:for 循环 - 支持 break 和 continue
const arr = [1, 2, 3, 4, 5]
for (let i = 0; i < arr.length; i++) {
if (arr[i] === 2) {
//break //退出当前循环
continue //跳过当前项
}
// console.log(arr[i])
}
// 方法二:forEach - ES5 新增 不支持 break 和 continue
arr.forEach(function (item) {
if (item === 2) {
//continue
}
// console.log(item)
})
//for 循环 和 forEach 有什么区别?for 循环支持 break 和 continue
// 方法三:every - ES5 新增 是否继续遍历取决于函数返回值,默认返回 false,return true 会使循环继续
arr.every(function (item) {
if (item === 2) {
return false
}
// console.log(item)
return true
})
// 方法四:for in - ES5 新增 为 object 遍历 支持 break 和 continue
// for in 可以遍历数组的两个因素:1、数组是对象 2、数组是可遍历的
// arr.a = 8
for (let index in arr) { // index 的数据类型是字符串
//if (index == 2) { //不判断数据类型
if (index * 1 === 2) { //第二种方式
//continue
break
}
// console.log(index, arr[index])
}
// 方法五:for of - 遍历 ES6 自定义数据(类型)对象
//for (variable of iterator) { //for…of 遍历的是一切可遍历的元素(数组、对象、集合)等.
//}
for (let item of arr) {
// console.log(item)
}
const Price = {
A: [3, 6, 7],
B: [5, 7, 9],
C: [9, 1, 5]
}
二、ES5中如何将伪数组转换成数组?什么是伪数组(Array-Like)?
DOM 中的 nodeList 集合、不定参 arguments,具备数组的特性如:长度、按索引方式储存数据(可遍历),它们和数组很像但是不具有数组拥有的方法,如:
let arrLike = {
0: ‘a’,
1: ‘b’,
2: ‘c’,
length: 3
}
伪数组转换成数组传统的做法是这样的:
let args = [].slice.call(arguments);
let imgs = [].slice.call(document.querySelectorAll('img'));
基本原理是使用 call 将数组的 api 应用在新的对象上,换句话说是利用改变函数的上下文来间接使用数组的 api。在 ES6 中提供了新的 api 来解决这个问题,就是 Array.from
let args = Array.from(arguments);
let imgs = Array.from(document.querySelectorAll('img'));
Array.from语法:Array.from(arrayLike[, mapFn[, thisArg]])
参数 | 含义 | 必选 |
---|---|---|
arrayLike | 想要转换成数组的伪数组对象或可迭代对象 | Y |
mapFn | 如果指定了该参数,新数组中的每个元素会执行该回调函数 | N |
thisArg | 可选参数,执行回调函数 mapFn 时 this 对象 | N |
ES5实现:初始化一个长度为 5 的数组,每个数组元素默认为 1
let arr = Array(6).join(' ').split('').map(item=>1)
// [1,1,1,1,1]
Array.from 实现会更简洁、更易理解:
Array.from({ length: 5 }, function () { return 1 })
三、ES5中创建一个新数组如何实现?ES6如何实现?
ES5生成新数组的两种方法:
// 方法一:生成一个长度为5,每个元素为空的数组
let array = Array(5);
// 方法二:字面量对象,不能指定长度
let array = [];
// ES6中生成新数组的方法:
// 方法一:Array.from
Array.from({ length: 5 }, function () { return 1 }) //上述方法
// 方法二:Array.prototype.of // ES6 允许快速将 n 个元素放到指定数组
// 业务场景:将多个元素放下数组,ES5 的实现方式是往事先声明的数组里依次 push 元素,ES6 可以用 Array.of 实现
let array = Array.of(1, 2, 3, 4, 5)
console.log(array) // [1, 2, 3, 4, 5]
//方法三:Array.prototype.fill //填充数组
// 业务场景:声明一个长度为5的数组并将每一个元素都初始化为 1
let array = Array(5).fill(1) // 比 Array.from 更简洁
console.log(array) //[1, 1, 1, 1, 1]
Array.fill 语法:arr.fill(value[, start[, end]])
参数 | 含义 | 必选 |
---|---|---|
value | 用来填充数组元素的值 | Y |
start | 起始索引,默认值为0 | N |
end | 终止索引,默认值为 this.length | N |
四、ES5 中如何查找一个元素?ES6 中如何实现?
// ES5 方法一:filter 找到与否都返回一个数组,通过判断数组长度来确定是否有要查找的元素
// filter特性:会把所有满足条件的元素都查找出来
// filter缺点:当业务需要验证某元素是否存在时性能不够高效(根据业务场景选择使用哪种方式,缺点只是相对而言)
let array = [1, 2, 3, 4, 5]
// let find = array.filter(function (item) {
// return item === 3
// // return item === 6 //[]
// })
// console.log(find) //[3]
// ES5 其它查找元素方法待延伸
// ES6 方法一:Array.prototype.find
// find特性:找到满足条件的第一个元素即返回,不再继续查找
let find = array.find(function (item) {
// return item === 2
// return item === 6 // undefined
return item % 2 == 0 // 2
})
console.log(find) // 2
// filter 和 find的区别:filter 关注的是满足条件的所有值,而 find 关注的是满足条件的第一个值,找到即返回。
// Array.prototype.findIndex 要查找的元素在数组中的索引值
let find = array.findIndex(function (item) {
// return item === 2
})
console.log(find) // 1
ES5 filter 和 ES6 find的区别:filter 关注的是满足条件的所有值,而 find 关注的是满足条件的第一个值,找到即返回。此外,ES6 还提供了 Array.prototype.findIndex 此方法返回要查找的元素在数组中的索引值