js高阶函数

一、高阶函数
      
 高阶函数是对其他函数进行操作的函数,可以将它们作为参数或通过返回它们。简单来说,高阶函数是一个函数,它接收函数作为参数或将函数作为输出返回
  •  是函数
  • 可以作为返回值
  • 可以作为参数
 
1、作为参数传递
 
    js函数可以传入变量,而函数也是一个变量,自然也可以传递
 
function add (x, y, f) {
    return f(x) + f(y)
}
let num = add(2, -2, function (a){return a })
console.log(num) // 0

 

 
2、作为返回值
 
    函数柯里化
 
let demo = function (x) {
    return function (y) {
        return x + y
    }
};
console.log(demo(3)) // Function(y){return 3 + y}
console.log(demo(3)(4)) // 7
这边只能够固定的两个参数,以下是通用的柯里化函数
 
方式一:
    思路:
  • 获取传入的函数, 函数的形参数,返回的函数
  • 获取每次调用返回函数时的实参
  • 实参等于形参时,执行传入函数,否则,继续返回函数
 
// 通用柯里化函数
const curry = (fn, ...arg) => {
    let all = arg || []; // 调用时的实参                     
    let length = fn.length; // 定义函数时形参个数
    return (...rest) => {
        let _args = all.slice(0); // 获取之前传入的实参,和当前调用时传入的参数合并
        _args.push(...rest);
        if (_args.length < length) { // 如果实参数小于形参数, 继续返回函数
            return curry.call(this, fn, ..._args);
        } else { // 如果实参数等于形参数,调用这个传递来的 函数
            return fn.apply(this, _args)
        }
    }
}
const add = curry((a,b) => a+b)
const item = add(1);
console.log(item(2)); // 3
 
方式二:
    思路:不获取形参数量,直接获取实参,然后传递,如果形参大于实参,返回的是一个函数,如果形参等于了实参,就执行函数
 
var curry1 = function(func){
    var args = [].slice.call(arguments,1); // 首先我们对通用函数截取参数
    return function(){
        var newArgs = args.concat([].slice.call(arguments)); //将每次添加的函数连接起来
        return func.apply(this,newArgs); //将此函数的数组赋给目标函数 并传入参数
    }
}
function sub(a,b){
    return a-b;
}
var subcurry = curry1(sub,5);
console.log(subcurry(3)); // 2
 
3、利用高阶函数实现filter/map/forEach/every/some
 
3.1.filter 
 
    过滤, 返回符合条件的元素
 
// 高阶函数实现filter
Array.prototype.myFilter = function (fn) {
    let arr = [];
    for(let i = 0; i < this.length; i++) {  // this指向的是Array实例
        let item = this[i]
        if (fn(item, i, this)) {
            arr.push(item)
        }
    }
    return arr
}
var arr = [1,2,3,4,5];
console.log(arr.myFilter((item, i, arr) => {
    return item > 2;
})) // [3,4,5 ]

 

 
3.2.map   
 
返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值
 
// Map
Array.prototype.myMap = function (fn) {
    let arr = []
    for(let i = 0; i < this.length; i++) {
        let item = fn(this[i], i, this) // 调用该函数
        arr.push(item)
    }
    return arr
}
var arr = [1,2,3,4];
console.log(arr.myMap((item, i, arr) => {
    return item*2;
})) // [2,4,6, 8]

 

 
3.3 forEach  
 
遍历数组、
 
// forEach()
Array.prototype.myForEach = function (fn) {
    for(let i = 0; i < this.length; i++ ) {
        fn(this[i], i, this)
    }
}
var arr = [1,2,3,4]
arr.myForEach((item, i, arr) => {
    console.log(item) // 1,2,3,4
})

 

 
3.4. every 
 
检测数组所有元素是否都符合指定条件
 
Array.prototype.myEvery = function(fn,value){
    var arr = this;
    for (var i = 0; i < arr.length; i++) {
        var result = fn.call(value, arr[i], i, arr);
        if (!result) return false;
    }
    return true;
}
var arr = [1,2,3,4]
console.log(arr.myEvery((item, i, arr) => {
    return item > 0 // true
}))
 

 

3.5.some  
 
 数组中有一个符合条件,就返回true
 
Array.prototype.mySome = function(fn, value){
    var arr = this;
    for (var i = 0; i < arr.length; i++) {
        var result = fn.call(value, arr[i], i, arr);
        if (result) return true;
    }
    return false;
}
var arr = [1,2,3,4]
console.log(arr.mySome((item, i, arr) => {
    return item < 0 // false
}))

 

 
 
posted @ 2020-05-22 17:04  whale~alince  阅读(252)  评论(0编辑  收藏  举报