3

JavaScript で次のコードを実行すると、「this.callback は関数ではありません」というエラーが表示されます

function ajaxRequest()
{
    var httpObject;

    this.open = open;
    this.callback = function(){};

    function getHTTPObject()
    {
        if (window.ActiveXObject) 
            return new ActiveXObject("Microsoft.XMLHTTP");
        else if (window.XMLHttpRequest)
            return new XMLHttpRequest();
        else 
        {
            alert("Your browser does not support AJAX.");
            return null;
        }
    }

    function onstatechange()
    {
        if(httpObject.readyState == 4)
        {
            this.callback(httpObject.responseText);
        }

    }


    function open(url, callback)
    {
        httpObject = getHTTPObject();
        if (httpObject != null) 
        {
            httpObject.open("GET", url, true);
            httpObject.send(null);
            this.callback = callback;
            httpObject.onreadystatechange = onstatechange;
        }
    }
}

open メソッドがコールバック パラメータを関数として扱わないのはなぜですか?

もしそうなら、なぜ私は onstatechange 関数でそれを呼び出せないのですか?

どうすればこれを機能させることができますか?

4

1 に答える 1

11

その理由は、なぜならonstatechangeがイベント ハンドラーとして呼び出されているためです。thisポインタは、予想どおり、オブジェクトではなく、イベントが発生したオブジェクトを指している可能性がありajaxRequestます。

以下の書き換えは、onstatechange() 関数がアクセスできる実行コンテキストでthis呼び出される変数に変数を格納します。thatこれで問題は解決するはずです。

要するに、Javascript のクロージャーと実行コンテキストを完全に理解していない場合です。理解していたとしても、フレームワークを使用して AJAX 要求を実行する方がはるかに優れています。jQuery と Prototype は良い選択です。

function ajaxRequest()
{
    var httpObject;

    this.open = open;
    this.callback = function(){};
    var that = this;

    function getHTTPObject()
    {
        if (window.ActiveXObject) 
                return new ActiveXObject("Microsoft.XMLHTTP");
        else if (window.XMLHttpRequest)
                return new XMLHttpRequest();
        else 
        {
                alert("Your browser does not support AJAX.");
                return null;
        }
    }

    function onstatechange()
    {
        if(httpObject.readyState == 4)
        {
                that.callback(httpObject.responseText);
        }

    }


    function open(url, callback)
    {
        httpObject = getHTTPObject();
        if (httpObject != null) 
        {
                httpObject.open("GET", url, true);
                httpObject.send(null);
                this.callback = callback;
                httpObject.onreadystatechange = onstatechange;
        }
    }
}
于 2009-01-19T07:28:38.217 に答える