从bind函数看js中的柯里化

以下是百度百科对柯里化函数的解释:柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。概念太抽象,可能并不怎么好理解,下面来举个栗子说明什么是函数柯里化。

 1 var obj = {
 2     name: "aaaaaaaaaa"
 3 };
 4 
 5 var name = "bbb";
 6 
 7 function fn(n1, n2) {
 8     console.log(this.name);
 9     console.log(n1 + n2);
10 }
11 
12 setTimeout(fn.bind(obj, 1, 2), 2000);

我们都知道bind函数作用与call和apply作用相似,但是与他们不同的是,bind函数不立即执行,而是简单的对函数做了一个预处理(加工)。等待调用的时候才执行。

但是这个函数方法并不兼容IE6-8,接下来我们自己实现一个myBind函数,功能类似bind

function myBind(fn, context) {

    var outerArg = Array.prototype.slice.call(arguments, 2);
    console.log(outerArg)

    return function() {

        fn.apply(context, outerArg);
    }
}

setTimeout(myBind(fn, obj, 1, 2), 2000);

主要实现思路是:首先把改变函数执行的上下文,这个我们用apply,因为后面如果要传参数,需要先截取数组,排除非参数项,得到是数组,所以就要用apply传参,call和apply的区别在这时就很明显。可以看到我们在函数中又返回了函数,如果不这样做,函数就会立即执行,那定时器就失去了意义。实际上这就体现了柯里化函数。对传入的参数做了预处理,然后再返回函数,函数调用时执行返回的函数。

接下来,我们把这个方法添加到函数对象的原型上。这里还需要改动一下,把其中的this指向改动一下。

 1 var obj = {
 2     name: "aaaaaaaaaa"
 3 };
 4 
 5 var name = "bbb";
 6 
 7 Function.prototype.myBind = function myBind(context) {
 8     var _this=this;
 9     var outerArg = Array.prototype.slice.call(arguments, 1);
10     return function() {
11 
12         _this.apply(context, outerArg);
13     }
14 }
15 
16 function fn(n1, n2) {
17     console.log(this.name);
18     console.log(n1 + n2);
19 }
20 
21 setTimeout(fn.myBind(obj, 1, 2), 2000);

到这里,你对函数柯里化的应该有了基本认识,有关函数柯里化还有更多博大精深的地方,不过你可以看到,其原理都是由基本的js知识构成的,然后通过这些基础知识才构思出来的,所以打好基础很重要。

前端发展速度之快,只有不断的学习积累,才能紧跟时代的步伐。
原文地址:https://www.cnblogs.com/zt123123/p/7641879.html