数组方法手写实现
map 和 filter的区别 find 和 findIndex的区别 filter 和 find的区别 forEach 和 单独的for循环区别 some 和 every的区别
自己写的类型检测
// 自己写的类型检测方法
class TypeCheck {
static common (vm) {
return Object.prototype.toString.call(vm).match(/^\[object\s(.*)\]$/)[1];
}
static isArray (that) {
return TypeCheck.common(that) === 'Array';
}
static isObject (that) {
return TypeCheck.common(that) === 'Object';
}
static isUndefined (that) {
return TypeCheck.common(that) === 'Undefined';
}
static isEmptyObject (that) {
let isObj = TypeCheck.isObject(that);
let isNull = false
if (isObj) {
isNull = Object.keys(that).length == 0;
}
return isObj && isNull;
}
static isNumber (that) {
let isNumber = TypeCheck.common(that) === 'Number';
let isNaN = TypeCheck.isNaN(that);
return isNumber && !isNaN;
}
static isNaN (that) {
return Number.isNaN(that);
}
}
forEach
/**
* 数组的forEach方法实现
* 功能遍历数组 且第二个参数 在不是箭头函数的情况下 可以改变this指向
*/
let obj = {
add: (x) => {
return x + 1
}
}
function myForEach(callback, thisArg) {
// 是否是一个方法
if (typeof callback != 'function') {
throw Error('不是一个方法')
}
let arr = this;
let that = thisArg;
if (that) {
for (const [index, value] of arr.entries()) {
callback.call(that, value, index, arr);
}
} else {
for (const [index, value] of arr.entries()) {
callback(value, index, arr);
}
}
}
Array.prototype.myForEach = myForEach;
// 这个thisArg 值对箭头函数无效
arr1.myForEach(function(item){
console.log(item)
console.log(this.add(item))
console.log('*********分割符号**********')
}, obj)
map
/*
数组的map 方法
功能:返回满足条件的新数组
*/
function myMap (callback) {
// 判断是否是函数
if (Object.prototype.toString.call(callback).match(/\[object\s(.*)\]$/)[1] !== 'Function') {
throw Error('不是一个函数');
}
let temp = [];
let arr = this;
for(let i = 0; i < arr.length; i++) {
temp.push(callback(arr[i], i, arr))
}
return temp;
}
Array.prototype.myMap = myMap;
let arr1 = [1, 2, 3, 4, 5, 6, 7]
let result = arr1.myMap((item) => {if(item==5){return item}})
console.log('result', result);
//[undefined, undefined, undefined, undefined, 5, undefined, undefined]
find
/*
数组的find 方法
功能: 查找符合条件的项,找不到返回undefined
*/
//callback 方法 () => {}
function myFind(callback) {
// callback 是否是函数
if (Object().toString.call(callback) != '[object Function]') {
return '这不是一个函数';
}
// 定义虚拟arr
let arr = this;
// 寻找的值
let findItem;
let arrLength = arr.length;
for (let i = 0; i < arrLength; i++) {
if (callback(arr[i], i, arr)) {
findItem = arr[i];
break;
}
}
return findItem;
}
Array.prototype.myFind = myFind;
let arr1 = [1, 2, 3]
let result1 = arr1.myFind((item, index, arr) => {return item === 4}) // undefined
let result2 = arr1.myFind((item, index, arr) => {return item ===1}) // 1
findIndex
/**
* findIndex
* 功能 找到符合条件的返回索引值 否则返回-1
*
*/
function myFindIndex(callback) {
if(typeof callback != 'function') {
throw Error('此函数不是一个方法');
}
const arr = this;
let findIndex = -1;
for(const [index, value] of arr.entries()) {
if(callback(value, index, arr)) {
findIndex = index;
break
}
}
return findIndex;
}
Array.prototype.myFindIndex = myFindIndex;
const arr = [{name: '孙悟空'}, {name: '猪八戒'}, {name: '唐僧'}]
let result1 = arr.myFindIndex(item => item.name == '沙悟净') //-1
let result2 = arr.myFindIndex(item => item.name == '猪八戒') // 1
console.log('结果一', result1, '\n结果二', result2)
filter
/**
* filter 方法
* 功能 返回新的数组 满足条件的数据
*/
function myFilter (callback) {
if (Object.prototype.toString.call(callback) !== '[object Function]') {
throw Error('不是一个方法')
}
let arr = this;
let filterArr = [];
for (const [index, value] of arr.entries()) {
callback(value, index, arr) ? filterArr.push(value) : '';
}
return filterArr;
}
Array.prototype.myFilter = myFilter;
let arrName = new Array({name: '张三'}, {name: '李四'}, {name: '王五'});
let target = arrName.myFilter((item) => item.name == '李四');
console.log(target)
some
/**
* some 方法
* 功能 当找到满足的值 结束遍历 返回boolean值
*/
let arrName = new Array({name: '张三'}, {name: '李四'}, {name: '王五'},{name: '赵六'});
function mySome (callback) {
if (typeof callback != 'function') {
throw Error('不是一个方法')
}
let arr = this;
let isHave = false
for(const [index, value] of arr.entries()) {
if (callback(value, index, arr)) {
isHave = true;
break
}
}
return isHave
}
Array.prototype.mySome = mySome;
let have1 = arrName.mySome((item) => item.name === '赵六');
let have2 = arrName.mySome((item) => item.name === '景七')
console.log(have1, have2)
every
/**
* every 方法
* 功能 当所有值都符合条件则返回true 否则返回false
*/
function myEvery (callback) {
if(typeof callback != 'function') {
throw Error('不是一个方法')
}
let arr = this;
let flag = true;
for(const [index, value] of arr.entries()) {
if (!callback(value, index, arr)) {
flag = false;
break
}
}
return flag;
}
Array.prototype.myEvery = myEvery
const arr = [{name: '招录'}, {name: '招录'}, {name: '招录'}]
let targetMy = arr.myEvery(item => item.name == '招录')
let unTargetMy = arr.myEvery( item => item.name == '没有')
console.log('targetMy', targetMy);
console.log('unTargetMy', unTargetMy);
用的比较少的方法
reduce
/**
* reduce 数组方法
* 功能 滚雪球遍历
*/
function myReduce(callback, init) {
if(Object.prototype.toString.call(callback) != '[object Function]') {
throw Error('不是一个方法')
}
let arr = this;
let start = init ? init : arr[0];
let result = "";
for (const [index, value] of arr.entries()) {
if (init) {
result = callback(start, value, index, arr);
} else {
if(index == 0) {
continue;
}
result = callback(start, value, index, arr);
}
start = result;
}
return result;
}
Array.prototype.myReduce = myReduce;
let target = [1, 2, 3, 4]
let result = target.myReduce((pre, current, index, arr)=> {
return pre+= current;
}, -1);
console.log(result) //9
flat
/**
* flat
* 功能 打平数组
*/
const arr = [1, [2], [3], [4,[8],9], [5, [6,[7]]]]
let origin = arr.flat()
console.log(origin)
console.log(' ==============与原的分割符号================')
function myFlat(number = 1) {
let arr = this;
let arrNew = [];
if (number <= 0) {
return arr;
}
// Infinity
if (number === Infinity) {
// return arrNew = JSON.stringify(arr).replace(/\[|\]/g, '').split(',');
const cycleArray = (array) => {
let arrTemp = [];
for(let i = 0; i < array.length; i++) {
if(Array.isArray(array[i])) {
arrTemp = arrTemp.concat(cycleArray(array[i]))
} else {
arrTemp.push(array[i])
}
}
return arrTemp
}
arrNew = cycleArray(arr);
return arrNew;
}
for (let i = 0; i < arr.length; i++) {
if(Array.isArray(arr[i])) {
arrNew = arrNew.concat(arr[i].myFlat(number - 1));
} else {
arrNew.push(arr[i]);
}
}
return arrNew
}
Array.prototype.myFlat = myFlat;
let target1 = arr.myFlat()
let target2 = arr.myFlat(2)
console.log(target1)
console.log('=========分割符===========')
console.log(target2)