我正在读一本书,其中包含以下示例:

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

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

因此,首选功能是:
var composition2 = function(f, g) {
  return function() {
    return f.call(this, g.apply(this, arguments));
  }
};

接下来是一个完整的示例:
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);

有人可以向我解释为什么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);

最佳答案

这只是回答composition2实际执行的操作:

当您想将composition2保留为函数本身的上下文时,可以使用this。以下示例通过使用60data.a显示结果为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

但是,它仍然破坏了以下示例(不幸的是):
'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

因为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 :)

或通过显式设置上下文:
'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]);

09-25 19:42