回调后引用自己

Referring to self after callback

javascript 中的 this 引用似乎在回调函数后不起作用。运行此代码时:

new Bla().start();

function Bla(){
    this.start = function(){
        alert("starting");
        x(this.done);
    }

    this.done = function(){
        alert("done");
        try{
            this.postDone();
        }
        catch(e){
            alert(e);
        }
    }

    this.postDone = function(){
        alert("postdone");
    }
}

function x(callback){
    alert("x");
    try{
        callback();
    }
    catch(e){
        alert(e);
    }
}

警报如下:

Starting
x
done
TypeError: undefined is not a function

我想知道为什么会出现这个问题,最好是解决这个问题的最佳实践。

您需要在此处上下文更改时保存对该上下文的引用,请在此处查看它如何存储在 ref 中并传递到参数中,然后使用 ...

调用

    new Bla().start();

    function Bla(){
        this.start = function(){
            alert("starting");
            x(this.done ,this);
        }

        this.done = function(){
            alert("done");
            try{
                var st = arguments[0];
                console.log(st); 
                st.postDone();
            }
            catch(e){
                alert(e);
            }
        }

        this.postDone = function(){
            alert("postdone");
        }
    }

    function x(callback,ref){
        alert("x");
        try{
          callback(ref);
        }
        catch(e){
            alert(e);
        }
    }

希望对您有所帮助...

像这样更改 x 函数调用,

this.start = function(){
    alert("starting");
    x(this.done.bind(this));
}

函数本质上不知道 "this" 对象。当一个函数被通过一个对象调用时,你只会得到一个"this"对象,例如obj.func()。只需调用 func() 就会得到一个 undefined "this" 对象。

我可以为您的代码想到三种可能的解决方案:

解决方案 1:将 "this" 对象与回调一起传递,并使用 call() 或 apply() 在其上调用回调

...
function Bla(){
    this.start = function(){
        alert("starting");
        x(this.done,this);
}
...
function x(callback,object){
    alert("x");
    try{
        callback.apply(object);
    }
    catch(e){
        alert(e);
    }
}

http://jsfiddle.net/4gt2u0y9/

解决方案 2:传递 "this" 对象和调用它的函数的名称

...
function Bla(){
    this.start = function(){
        alert("starting");
        x(this,'funcName');
}
...
function x(object,funcName){
    alert("x");
    try{
        object[funcName]();
    }
    catch(e){
        alert(e);
    }
}

http://jsfiddle.net/4gt2u0y9/1/

解决方案 3:仅传递 "this" 对象,并让回调客户端采用回调名称

...
function Bla(){
    this.start = function(){
        alert("starting");
        x(this);
}
...
function x(callbackServer){
    alert("x");
    try{
        callbackServer.done();
    }
    catch(e){
        alert(e);
    }
}

http://jsfiddle.net/4gt2u0y9/2/