Js中的函数

本文详细探讨了JavaScript中的函数,包括函数柯里化及其好处,如参数复用、提前确认和延迟运行。此外,介绍了Js中的高阶函数,如map、reduce、filter、sort以及Array的方法。还涉及了Generator函数和async/await在异步编程中的应用,展示了它们如何简化异步操作。
摘要由CSDN通过智能技术生成

函数柯里化

柯里化概念:只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数
看一个例子:

var add = function(x) {
  return function(y) {
    return x + y;
  };
};

var increment = add(1);
var addTen = add(10);

increment(2);
// 3

addTen(2);
// 12

我们定义了一个add函数,它接受一个参数并返回一个新的函数。调用了add之后,返回的函数就通过闭包的方式记住了add的第一个参数。

因为一次性地调用它有点繁琐,所以使用一个特殊的curry帮助函数使得这类函数的定义和调用更加容易。

curry的封装

// 初步封装
var currying = function(fn) {
    // args 获取第一个方法内的全部参数
    var args = Array.prototype.slice.call(arguments, 1)
    return function() {
        // 将后面方法里的全部参数和args进行合并
        var newArgs = args.concat(Array.prototype.slice.call(arguments))
        // 把合并后的参数通过apply作为fn的参数并执行
        return fn.apply(this, newArgs)
    }
}

这边首先是初步封装,通过闭包把初步参数给保存下来,然后通过获取剩下的arguments(这里的arguments是函数function自带的一个隐式参数,表现为所有参数组成的数组)进行拼接,最后执行需要currying的函数。

但是好像还有些什么缺陷,这样返回的话其实只能多扩展一个参数,currying(a)(b)(c)这样的话,貌似就不支持了(不支持多参数调用),一般这种情况都会想到使用递归再进行封装一层。

// 支持多参数传递
function progressCurrying(fn, args) {

    var _this = this
    var len = fn.length;
    var args = args || [];

    return function() {
        var _args = Array.prototype.slice.call(arguments);
        Array.prototype.push.apply(args, _args);

        // 如果参数个数小于最初的fn.length,则递归调用,继续收集参数
        if (_args.length < len) {
            return progressCurrying.call(_this, fn, _args);
        }

        // 参数收集完毕,则执行fn
        return fn.apply(this, _args);
    }
}

拓展一道经典的面试题

// 实现一个add方法,使计算结果能够满足如下预期:
// add(1)(2)(3) = 6;
// add(1, 2, 3)(4) = 10;
// add(1)(2)(3)(4)(5) = 15;

function add() {
    // 第一次执行时,定义一个数组专门用来存储所有的参数
    var _args = Array.prototype.slice.call(arguments);

    // 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值
    var _adder = function() {
        console.log("接收了一个()");
        _args.push(...arguments); //...arguments在ES6中表示剩下所有的参数,接受剩下的所有参数
        return _adder; //再返回adder,进行下一次递归,把上次接收的结果作为第一个参数,
        //再接受下一个参数,这里相当于接受下一个()里的参数,直到接收完毕

    };

    // 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
    _adder.toString = function() {
         // return _args.reduce(function(a, b) {
        //     return a + b;
        // });
        return _args.reduce((a, b) => a + b);
        //reduce是ES5中的API,利用其能够遍历到数组的每一个元素,这里的a+b相当于当前所有的参数
    }
    return _adder; //这里相当于返回最后计算好的结果
}

var res = add(1, 2)(1)(2)(5);
console.log(re
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值