如何重写函数而不是引用?

时间:2013-07-15 09:47:40

标签: javascript jasmine

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函数而不是间谍。

我想知道如何覆盖该功能,而不仅仅是它的参考。

1 个答案:

答案 0 :(得分: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,这样更安全,因为它允许您选择一个不同的“内部”函数,而不会改变代码的核心行为。