扩展作为参数传递的Javascript函数

时间:2009-01-08 18:55:48

标签: javascript

我有一个javascript函数(类),它将函数引用作为一个paremter。

function MyClass ( callBack ) {
  if (typeof callBack !== 'function')
    throw "You didn't pass me a function!"
}

由于我不会进入这里的原因,我需要通过将它包含在一个匿名函数中来附加函数,但我能够弄清楚如何做到这一点的唯一方法是添加一个 MyClass 的公共函数,它将callBack函数作为参数并返回修改后的版本。

function MyClass () {
    this.modifyCallBack = function ( callBack ) {
       var oldCallBack = callBack;
       callBack = function () {
           oldCallBack(); // call the original functionality
           /* new code goes here */
       }
       return callBack;
    }
}

/* elsewhere on the page, after the class is instantiated and the callback function defined */
myCallBackFunction = MyClassInstance.modifyCallBack( myCallBackFunction );

将callBack函数作为参数传递给类时,是否可以使这个工作成功?在将其作为参数传递时尝试以这种方式修改函数似乎只影响它在类中的实例,但这似乎不是一个有效的假设,因为函数是javascript中的对象,因此通过参考

更新:正如crescentfresh指出的那样(我没能解释得很好),我想在原地修改callBack函数。如果在实例化类时可以执行所有这些操作,我宁愿不调用第二个函数。

4 个答案:

答案 0 :(得分:5)

函数对象不提供修改它们的方法。因此,您想要做的事情是不可能的。 Jon Skeet喜欢指出Java也是一样:对象并不是真正通过引用传递,而是通过值传递指向它们的指针。这意味着将参数变量的值更改为新变量将不会影响原始参数变量。

只有两种方法可以在Java和JavaScript等按值调用语言中执行您想要的操作:第一种方法是使用(函数)对象的方法来修改它。正如我已经说过的,函数对象没有那些。另一个是将函数对象作为属性的对象作为第二个参数传递,并将相应的属性设置为包装旧函数的新函数。

示例:

var foo = {};
foo.func = function() {};

function wrapFunc(obj) {
    var oldFunc = obj.func;
    obj.func = function() {
        // do some stuff
        oldFunc.call(obj, _some_argument__);
    };
}

wrapFunc(foo);

这也适用于全局函数:它们是window对象的属性。

答案 1 :(得分:1)

由于Javascript在变量上使用词法范围,因此可以采用以下方法:

var modifiableCallback=function() { alert('A'); };


function ModifyCallbackClass(callback)
{
    modifiableCallback=function() { callback(); alert('B'); };  
}


function body_onload()
{

    var myClass=new ModifyCallbackClass(modifiableCallback);

    modifiableCallback();

}

这样做你想要的,但是必须在ModifyCallbackClass中使用相同的名称引用函数“modifiableCallback”,否则不会应用闭包。所以这可能会限制这种方法对你的用处。

使用eval(性能可能会受到一些影响),也可以使这种方法更灵活:

var modfiableCallback1=function() { alert('A'); };

var modfiableCallback2=function() { alert('B'); };

var modfiableCallback3=function() { alert('C'); };

function ModifyCallbackClass(callbackName)
{
    var temp=eval(callbackName);
    var temp2=eval(callbackName);

    temp= function() { temp2(); alert('Modified'); };

    eval(callbackName + " = temp;");
}


function body_onload()
{

    var myClass=new ModifyCallbackClass("modfiableCallback1");

    modfiableCallback1();

    myClass=new ModifyCallbackClass("modfiableCallback2");

    modfiableCallback2();

    myClass=new ModifyCallbackClass("modfiableCallback3");

    modfiableCallback3();

}

答案 2 :(得分:0)

我假设你在某个地方保存这个回调......这有什么理由不起作用?

function MyClass ( callBack ) {
  var myCallBack;

  if (typeof callBack !== 'function')
    throw "You didn't pass me a function!"

  var oldCallBack = callBack;
  callBack = function () {
    oldCallBack(); // call the original functionality
     /* new code goes here */
  }
  myCallBack = callback;
}

答案 3 :(得分:0)

你想做类似的事情:

function MyClass () {
    this.modifyCallBack = function ( callBack ) {
        var oldCallBack = callBack;
        callBack = function () {
            oldCallBack(); // call the original functionality
            alert("new functionality");
        }
        return callBack;
    }
}

/* elsewhere on the page, after the class is instantiated and the callback function defined */
var myCallBackFunction = function () {alert("original");};
var MyClassInstance = new MyClass();
myCallBackFunction = MyClassInstance.modifyCallBack( myCallBackFunction );
myCallBackFunction();