将两个函数引用传递给构造函数在Javascript

时间:2017-09-20 11:18:41

标签: javascript constructor javascript-objects

我想在javascript中创建对象的实例。我尝试将两个函数引用传递给另一个类的构造函数。但它会抛出如下错误:

  

this.onFailFunction不是函数

但是,如果我只传递一个引用(onSuccess),它就可以工作。有什么区别?

的index.html

<script>

            function onSuccess(data, message)
            {
                console.log(data);
                console.log(message);
            }


            function onFail(data, message, errorCode)
            {
                console.log(data);
                console.log(message);
                console.log(errorCode);
            }
            var callBack = new EbookCallBack(onSuccess, onFail);
            callBack.mainCallback.callSuccessFunction({success:false, message:"Wovvv", errorcode:1, data:"asdsa"});

        </script>

ebookcallback.js

class EbookCallBack 
{

    constructor(onSuccessFunction, onFailFunction) 
    {
        this.onSuccessFunction = onSuccessFunction;
        this.onFailFunction = onFailFunction;
        this.mainCallback = new CallBack(this.onSuccess, this.onError);
    }

    onSuccess(result) 
     {
        if(result.success)
        {
            this.onSuccessFunction(result.data, result.message);
        }
        else
        {
            this.onFailFunction(result.data, result.message, result.errorcode);
        }
    }

    onError(message) 
    {
        if(this.onErrorFunction !== undefined) 
        {
            this.onErrorFunction(message);
        } 
    }


}

maincallback.js

class CallBack 
{

    constructor(onSuccessFunction, onErrorFunction) 
    {
        this.onSuccessFunction = onSuccessFunction;
        this.onErrorFunction = onErrorFunction;
    }

    callSuccessFunction(data) 
    {
        this.onSuccessFunction(data);
    }

    callErrorFunction(message) 
    {
        this.onErrorFunction(message);
    }

}

3 个答案:

答案 0 :(得分:3)

你的问题从这一部分开始:

this.mainCallback = new CallBack(this.onSuccess, this.onError);

因为它会在this.onSuccess对象没有任何连接的情况下传递函数this.onErrorEbookCallBack(无论如何都没有定义),所以稍后此函数中的this指的是全局对象,而不是EbookCallBack

因此,如果在callSuccessFunction上调用CallBack,则此函数会调用this.onSuccessFunction(data),然后调用您最初从onSuccess传递的EbookCallBack函数,但是这个函数将在全局对象的上下文中调用,而不是在EbookCallBack的一个中调用。

您需要使用bind

this.mainCallback = new CallBack(this.onSuccess.bind(this), this.onError.bind(this) );

this.onError.bind(this)现在会失败,因为onError未定义)

答案 1 :(得分:1)

&#34;这&#34;正在迷失。在EbookCallback内部,

onSuccess(result) 
 {
    if(result.success)
    {
        this.onSuccessFunction(result.data, result.message);
    }
    else
    {
        this.onFailFunction(result.data, result.message, result.errorcode);
    }
}

我在chrome devtools中设置了一个断点,当你到达this.onFailFunction时,&#34;这个&#34;是CallBack类,而不是EbookCallback类。那是因为当你调用this.onSuccessFunction(data);时,上下文被设置为CallBack对象

你可以修复&#34;这个&#34;将new CallBack(this.onSuccess, this.onError);替换为new CallBack(this.onSuccess.bind(this), this.onFailFunction.bind(this));

修改

我发现没有人提供“绑定”的潜在替代品

this.mainCallback = new CallBack(this.onSuccess, this.onError);可以更改为以下内容:

this.mainCallback = new CallBack(function(result){
    this.onSuccess(result);
}, function(message){
    this.onError(message);
});

对于某些人来说,这个解决方案可能更直观。

答案 2 :(得分:-1)

这似乎是一个有约束力的问题。当你这样做时:

callErrorFunction(message) 
{
   this.onErrorFunction(message);
}

...您正在调用EbookCallBack课程中的该函数,但您的this变量已绑定到当前对象(Callback),即使您在&#39 ;重新执行不同类中的代码。

基本上,在javascript中使用this非常困难且令人困惑。如果你能提供帮助,我通常建议你不要这样做。许多程序员尝试编写javascript,好像它是Java并将所有东西都包装在对象中,但你真的根本不需要这样做! (在以前的生活中,你是否有机会成为Java编码器?)

javascript中的OOP样式在this中添加了大量样板和错误。您可能会发现功能样式更具可读性和可维护性。看看这个:

//just a plain JS object, not a class
var myCallbacks = {
    onSuccess: function( data, message ) {
       //do something
    },
    onFail: function( data, message, errorCode ) {
       //do something else
    }
};

tryTheThing( "fish", myCallbacks );

function tryTheThing( data, myCallbacks ) {
   if ( data === "fish" ) {
      myCallbacks.onSuccess(data, "Yay");
   } else {
      myCallbacks.onFail(data, "boo", 51);
   }
}

更简单,对吧?不需要课程或this。或者甚至更好,使用Javascript Promises,它已经封装了这种行为:

tryTheThing( "fish" )
   .then( function( data, message ) {
      //success
   }).catch( function( data, message, errorcode ) {
      //fail
   });

function tryTheThing( data ) {
   return new Promise( function( resolve, reject ) { 
      if ( data === "fish" ) {
         resolve( data, "yay" );
      } else {
         reject( data, "boo", 51 );
      }
   });
}

Promise现在是javascript的核心部分,是处理回调而不会污染函数参数的好方法!