forEach、map、reduce、filter高阶函数
高阶函数,指的是JavaScript的函数其实都指向某个变量。既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称为高阶函数。
1、forEach
其中forEach方法中的function回调支持三个参数,第一个是遍历的数组内容;第二个的应用的数组索引,第三个是数组本身。
1
| [].forEach(funciton(value,index,array))
|
同时forEach也是可以第一个参数传回调,第二个参数传this,去改变,不传则默认为window,严格模式下将会是undefined。
1 2 3 4
| var arr = [1,2,3] delete arr[1]; console.log(arr) array.forEach(alert)
|
同时forEach是不会遍历空元素的。
2、map
1 2 3 4
| array.map(callback,[ thisobject ]) [].map(function(value, index, array){ })
|
就是将原来的数组映射成新的数组
callback需要return值,不然将全部是undefined
1 2 3 4 5 6 7 8 9 10 11 12
| Array.prototype.mymap = function (fn, context) { let arr = []; let _this = context ? contet : this; if (fn instanceof Function) { _this.forEach((item, _this) => { arr.push(fn.call(_this, item)); }) } else { throw new Error("${fn} is not a function") } return arr; }
|
3、filter
这就是一个过滤器,语法类似mapjsilter的callback需要返回布尔值,true表示通过的,false表示不需要的
1 2 3 4 5 6 7 8 9 10 11 12 13
| Array.prototype.myfilter = function (fn, context) { let arr = []; let _this = context ? context : this; if (fn instanceof Function) { _this.forEach(element => { if (fn(element)) arr.push(element); }); } else { throw new Error("func is not a function") } return arr; }
|
4、reduce
功能是用于迭代的
1
| arr.reduce(callback,[initialValue])
|
其中callback可以包含四个参数
- previous:上次调用回调返回的结果,或者是提供的初始值(initialValue)
- currentValue(数组当前被处理的元素)
- index(当前元素在数组中的引用)
- array(调用reduce的数组)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| let arr = [1,2,3,4,4,1] let newArr = arr.reduce((pre,cur)=>{ if(!pre.includes(cur)) return pre.concat(cur); else return pre; },[])
let arr = [[0,1], [2,3], [4,5]] let newArr = arr.reduce((pre,cur)=>{ return pre.concat(cur) },[]) console.log(newArr);
let arr = [[0,1],[2,3],[4,[5,6,7]]] const newArr = function(arr){ return arr.reduce((pre,cur)=>pre.concat(Array.isArray(cur)?newArr(cur):cur),[]) }
|
5、flat
1 2 3 4 5 6 7
| Array.prototype.flat(level)
arr.flat(Infinity)
[1,2,,4,5].flat()
|
同时还有一个flatMap方法,相当于对原数组每个元素执行一次map,再拉平
1 2 3 4 5 6 7
| Array.prototype.myflat = fucntion(d=1){ let arr = this return d>0?reduce((acc,cur) => { acc.concat(Array.isArray(val)?val.myflat(d-1):val) },[]):arr.slice() }
|
6、手写instanceof
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| function instance_of(L, R) { const baseType = ['string', 'number', 'boolean', 'undefined', 'symbol'] if (baseType.includes(typeof (L))) { return false; } let RP = R.prototype; L = L.__proto__; while (true) { if (L === null) { return false; } if (L === RP) { return true; } L = L.__proto__; } } console.log(instance_of(Array, Object)) console.log(Array instanceof Object)
|
7、call、apply、bind
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| Function.prototype._call = function(obj){ var _obj = obj ? Object(obj) : window _obj.fn = this; var argArr = Array.from(arguments).slice(1) _obj.fn(...argArr); delete _obj.fn }
function test(X,y,z){ console.log(X+y+z) console.log(this.name); } var obj = { name:'啥名字' } test._call(obj,'啥','名','字'); console.log(obj)
Function.prototype._apply = function(obj, argArr) { var _obj = obj ? obj : window _obj.fn = this var arg = [] if (!argArr || argArr.length == 0) { _obj.fn() } else { for (var i = 0; i < argArr.length; i++) { arg.push(argArr[i]) } _obj.fn(...arg); } delete _obj.fn }
function test(x,y,z) { console.log(x+y+z); console.log(this.name); } var obj = { name: '前端菜鸟库' } test._apply(obj, ['菜鸟', '库','233']) console.log(obj)
Function.prototype._bind = function (obj) { if(typeof(this) !== "function"){ throw Error("调用_bind方法的必须为函数") } var args = Array.prototype.slice.call(arguments,1) var _fn = this; var bindFn = function(){ var newArgs = Array.prototype.slice.call(arguments) var _obj = this.constructor === _fn ? this:obj _fn.apply(_obj,newArgs.concat(args)) } var ProtoFn = function(){} ProtoFn.prototype = _fn.prototype bindFn.prototype = new ProtoFn() return bindFn; }
var obj = { name: "前端菜鸟库" } function test(x,y,z) { this.age = '18' console.log(this.name) console.log('x:',x,'y:',y,'z:',z) console.log(x+y+z) } test.prototype.book = "JS" var Bound = test._bind(obj, 1, 2, 3) Bound()
|