0
var BigObject = (function() {

  function deepCalculate(a, b, c) {
    return a + b + c;
  }

  function calculate(x) {
    deepCalculate(x, x, x);
  }

  return {
    calculate: calculate,
    api: {        
      deepCalculate: deepCalculate
    }
  }
})();

这是我保留的带有私有功能的基本自我执行功能api。我遇到的问题是现在我无法deepCalculate从函数外部覆盖。

这怎么成问题?我使用Jasmine并想测试是否调用了函数。例如:

spyOn(BigObject, 'calculate').andCallThrough();
expect(BigObject.api.deepCalculate).toHaveBeenCalled();

失败。但是,当我调试时,我确信 Jasmine 绑定BigObject.api.deepCalculate为间谍,但是从内部计算仍然调用原始deepCalculate函数而不是间谍。

我想知道如何覆盖该函数而不仅仅是它的参考。

4

1 回答 1

0

简单的答案是:

(function ()
{
    var overWriteMe = function(foo)
    {
        return foo++;
    },
    overWrite = function(newFunc)
    {
        for (var p io returnVal)
        {
            if (returnVal[p] === overWriteMe)
            {//update references
                returnVal[p] = newFunc;
                break;
            }
        }
        overWriteMe = newFunc;//overwrite closure reference
    },
    returnVal = {
        overWrite: overWrite,
        myFunc: overWriteMe
    };
}());

尽管我必须这么说,但我会认真考虑替代方法来实现您想要做的任何事情。一个闭包,IMO,应该作为一个整体来对待。随意替换它的一部分很快就会被证明是一场噩梦:你不知道闭包函数在任何给定的时间点是什么,它在哪里被改变,之前的状态是什么,以及它为什么被改变。
一个临时的解决方案可能就是这样:

var foo = (function()
{
    var calc = function(x, callback)
    {
        callback = callback || defaultCall;
        return callback.apply(this, [x]);
    },
    defaultCall(a)
    {
        return a*a+1;
    },
    return {calc: calc};
}());
foo(2);//returns 5
foo(2,function(x){ return --x;});//returns 1
foo(2);//returns 5 again

IMO,这要安全得多,因为它允许您选择一个不同的“内部”函数来使用一次,而不会改变代码的核心行为。

于 2013-07-15T10:05:44.617 回答