数组
数组作为js八种数据类型的一种,其作用是使用单独的变量名来储存一系列的值。
对于typeof
判断的值为object
。
1.数组判断
1.1 constructor
console.log([1,2].constructor === 'Array')
原理:通过查看变量的构造函数来判断改变量是否为数组类型。
缺点: 若对象原型被修改,判断则不准确。
1.2 Object.prototype.toString.call()
console.log(Object.prototype.toString.call([1,2]).slice(8,-1) === 'Array')
原理:通过调用Object原型上的toString()方法查看变量原型,再通过截取字符串进行判断。
1.3 原型链判断
let arr = [1,2]
console.log(arr.__proto__ === Array.prototype) //或
console.log(Object.getPrototypeOf(arr) === Array.prototype)
原理,通过查看对象的隐式原型与构造函数的显式原型来判断是否为数组类型。
1.4 instanceof
console.log([1,2] instanceof Array)
原理:通过循环找出变量的__proto__来与构造函数的原型作比较,判断变量是否是Array构造函数的对象实例。
1.5 Array.isArray()
console.log(Array.isArray([1,2]))
原理:es6附带方法
1.6 Array.prototype.isPrototypeOf
console.log(Array.prototype.isPrototypeOf([1,2]))
2. 数组求和
2.1 reduce()(常规数组)
let arr = [1,2,3,4,5,6,7,8,9]
let sum = arr.reduce((total,i) => total + i, 0)
console.log(sum) //45
2.2 toString()(嵌套数组)
let arr = [1,2,3,[[4,5],6],7,8,9]
let sum = arr.toString().split('').reduce((total,i) => total += i, 0)
console.log(sum) //45
2.3 递归实现(常规数组)
let arr = [1,2,3,4,5,6,7,8,9]
function addArr(arr) {
if(arr.length === 1) return arr[0]
return arr[0] + addArr(arr.slice(1))
}
3.数组扁平化
将嵌套数组转化为一维数组
3.1 toString实现
let arr = [1,2,3,[[4,5],6],7,8,9]
let newArr = arr.toString().split(',').map(Number)
console.log(newArr) // [1,2,3,4,5,6,7,8,9]
3.2 ES6 flat()
let arr = [1,2,[3,4]]
let newArr = arr.flat(Infinity)
flat(depth)接收参数为Number类型,表示传递数组的展开深度,若层数不确定,则传入Infinity。
3.3 JSON.stringify(),正则
let arr = [1,2,[3,4]]
let str = '[' + JSON.stringify(arr).replace(/(\[|\])/g,'') + ']'
console.log(JSON.parse(str)) // [1,2,3,4]
3.4 扩展运算符和some()
let arr = [1,2,[3,4]]
while(arr.some(item => Array.isArray(item))) {
[].arr.concat(...arr)
}
console.log(arr) //[1,2,3,4]
3.5 reduce()递归迭代
let arr = [1,2,[3,4]]
function flatten(arr) {
return arr.reduce(function(pre,next) {
return pre.concat(Array.isArray(next) ? flatten(next) : next)
},[]) //初值 []
}
console.log(flatten(arr)) // [1,2,3,4]
3.6 常规递归
let arr = [1,2,[3,4]]
function flatten(arr) {
let result = []
arr.forEach(item => {
if(Array.isArray(item)) {
result = result.concat(flatten(item))
} else {
result.push(item)
}
})
return result
}
console.log(flatten(arr)) //[1,2,3,4]
4. 数组去重
4.1 Set数据结构
let arr = [1,1,2,2,3,4,4,4]
let newArr = Array.from(new Set(arr))
console.log(newArr) // [1,2,3,4]
4.2 遍历储存重复数字
let arr = [1,1,2,2,3,4,4,4]
let newArr = []
let map = {}
arr.forEach(item => {
if(!map.hasOwnProperty(item)) {
map[item] = 1
newArr.push(item)
}
})
console.log(newArr) //[1,2,3,4]
数组flat()方法实现
function myFlat(arr, depth) {
if(!Array.isArray(arr) || depth <= 0) {
return arr;
}
return arr.reduce((prev, cur) => {
if (Array.isArray(cur)) {
return prev.concat(myFlat(cur, depth - 1))
} else {
return prev.concat(cur);
}
}, []);
}
数组push()方法实现
Array.prototype.myPush = function() {
for(let i = 0; i < arguments.length; i ++) {
this[this.length] = arguments[i]
}
return this.length
}
数组flter()方法实现(不包括实现键值对)
Array.prototype.myFlter= function(fn) {
if(typeof fn !== 'function') {
console.err('参数必须是一个函数')
}
let res = []
for(let i = 0; i < this.length; i ++) {
if(fn(this[i])) {
res.push(this[i])
}
}
return res
}
数组map()方法实现(不包括实现键值对)
Array.prototype.myMap = function(fn) {
if(typeof fn !== 'function') {
console.err('参数必须是一个函数')
}
let res = []
for(let i = 0; i < this.length; i ++) {
res.push(fn(this[i]))
}
return res
}