JavaScript组成函数

JSh*_*ami 6 javascript function-composition

我正在读一本包含以下示例的书:

var composition1 = function(f, g) {
  return function(x) {
    return f(g(x));
  }
};
Run Code Online (Sandbox Code Playgroud)

然后作者写道:"......组合的天真实现,因为它不考虑执行上下文......"

所以首选的功能是:

var composition2 = function(f, g) {
  return function() {
    return f.call(this, g.apply(this, arguments));
  }
}; 
Run Code Online (Sandbox Code Playgroud)

接下来是一个完整的例子:

var composition2 = function composition2(f, g) {
    return function() {
        return f.call(this, g.apply(this, arguments));
    }
};

var addFour = function addFour(x) {
    return x + 4;
};

var timesSeven = function timesSeven(x) {
    return x * 7;
};

var addFourtimesSeven2 = composition2(timesSeven, addFour);
var result2 = addFourtimesSeven2(2);
console.log(result2);
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释为什么composition2功能是首选的(可能有一个例子)?

编辑:

与此同时,我试图使用方法作为建议的参数,但它没有用.结果是NaN:

var composition1 = function composition1(f, g) {
    return function(x) {
        return f(g(x));
    };
};

var composition2 = function composition2(f, g) {
    return function() {
        return f.call(this, g.apply(this, arguments));
    }
};

var addFour = {
    myMethod: function addFour(x) {
        return x + this.number;
    },
    number: 4
};

var timesSeven = {
    myMethod: function timesSeven(x) {
        return x * this.number;
    },
    number: 7
};

var addFourtimesSeven1 = composition1(timesSeven.myMethod, addFour.myMethod);
var result1 = addFourtimesSeven1(2);
console.log(result1);

var addFourtimesSeven2 = composition2(timesSeven.myMethod, addFour.myMethod);
var result2 = addFourtimesSeven2(2);
console.log(result2);
Run Code Online (Sandbox Code Playgroud)

Car*_*iel 2

这只是回答了composition2实际的情况:

composition2this当您想在函数本身中保留上下文时使用。60以下示例显示使用data.aand得出的结果data.b

'use strict';

var multiply = function(value) {
    return value * this.a;
}
var add = function(value) {
    return value + this.b;
}

var data = {
    a: 10,
    b: 4,
    func: composition2(multiply, add)
};

var result = data.func(2);
// uses 'data' as 'this' inside the 'add' and 'multiply' functions
// (2 + 4) * 10 = 60
Run Code Online (Sandbox Code Playgroud)

但是,它仍然破坏了以下示例(不幸的是):

'use strict';

function Foo() {
    this.a = 10;
    this.b = 4;
}
Foo.prototype.multiply = function(value) {
    return value * this.a;
};
Foo.prototype.add = function(value) {
    return value + this.b;
};


var foo = new Foo();

var func = composition2(foo.multiply, foo.add);
var result = func(2); // Uncaught TypeError: Cannot read property 'b' of undefined
Run Code Online (Sandbox Code Playgroud)

composition2由于( )的上下文this未定义(并且不会以任何其他方式调用,例如.apply,.callobj.func()),因此您最终也会this在函数中未定义。

另一方面,我们可以使用以下代码为其提供另一个上下文:

'use strict';
var foo = new Foo();

var data = {
    a: 20,
    b: 8,
    func: composition2(foo.multiply, foo.add)
}

var result = data.func(2); 
// uses 'data' as 'this'
// (2 + 8) * 10 = 200 :)
Run Code Online (Sandbox Code Playgroud)

或者通过显式设置上下文:

'use strict';

var multiply = function(value) {
    return value * this.a;
};
var add = function(value) {
    return value + this.b;
};


var a = 20;
var b = 8;

var func = composition2(multiply, add);

// All the same
var result1 = this.func(2);
var result2 = func.call(this, 2);
var result3 = func.apply(this, [2]);
Run Code Online (Sandbox Code Playgroud)