JavaScript “is not a function” error when calling defined method

情到浓时终转凉″ 提交于 2020-01-01 01:25:09

问题


This is my code:

request_xml: function()
        {
        http_request = false;
                    http_request = new XMLHttpRequest();
                     if (http_request.overrideMimeType) 
                            {
                            http_request.overrideMimeType('text/xml');
                            }
                          if (!http_request)
                          {
                                return false;
                          }
                        http_request.onreadystatechange = this.response_xml;
                        http_request.open('GET', realXmlUrl, true);
                        http_request.send(null);
                        xmlDoc = http_request.responseXML;

},



response_xml:function ()
    {
        if (http_request.readyState == 4)
        {
            if(http_request.status == 404 && countXmlUrl<=3)
            {
                countXmlUrl++;

                realXmlUrl = xmlUrl[countXmlUrl];
                this.request_xml();
            }
            if (http_request.status == 200)
            {
                xmlDoc = http_request.responseXML;
                alert("need to update3");
                this.peter_save_data();
            }

        }
    },

peter_save_data:function()
    {
// removed function code
},

Strangely, the alert fires without a problem but the function call underneath gives me this error:

Error: this.peter_save_data is not a function

Calling the same damn function from another function elsewhere works fine.


回答1:


You could do this, right before you call the XML generation.

var that = this;

and later...

that.peter_save_data();

Because this frequently changes when changing scope by using a new function, you can't access the original value by using it. Aliasing it to that allows you still to access the original value of this.




回答2:


One important piece of the puzzle that is missing is how response_xml is being called. This is important, because it will change what this is (see Jared's comment).

Remember that this can be thought of as (roughly) "the receiver of the method call". If response_xml is passed directly to use as a callback then of course it won't work -- this will likely be window.

Consider these:

var x = {f: function () { return this }}
var g = x.f
x.f() === x    // true
g() === x      // false
g() === window // true

Happy coding.


The "fix" is likely just to change how response_xml is being called. There are numerous ways to do this (generally with a closure).

Examples:

// Use a closure to keep he object upon which to explicitly invoke the method
// inside response_xml "this" will be "that",
// which was "this" of the current scope
http_request.onreadystatechange = (function (that) {
   return function () { return that.response_xml() }
}(this)

// Or, alternatively,
// capture the current "this" as a closed-over variable...
// (assumes this is in a function: var in global context does not create a lexical)
var self = this
http_request.onreadystatechange = function () {
   // ...and invoke the method upon it
   return self.response_xml()
}

Personally, I would just use jQuery or similar ;-)




回答3:


If you want a class-like behavior, use the right syntax, The libraries that use that, are using JSON to pass a parameter to a function that makes a class out of it.

function MyClass(CTOR paarams){
    var response_xml=function ()
    {
        if (http_request.readyState == 4)
        {
            if(http_request.status == 404 && countXmlUrl<=3)
            {
                countXmlUrl++;

                realXmlUrl = xmlUrl[countXmlUrl];
                this.request_xml();
            }
            if (http_request.status == 200)
            {
                xmlDoc = http_request.responseXML;
                alert("need to update3");
                this.peter_save_data();
            }

        }
    }

    var peter_save_data=function()
    {
       // removed function code
    }
}

var Test = new MyClass(somthing,another_something);
Test.response_xml();
//etc etc.

Or, use the libraries like Mootools where you can do it as JSON:

var T = new Class({
    response_xml:function ()
    {
        if (http_request.readyState == 4)
        {
            if(http_request.status == 404 && countXmlUrl<=3)
            {
                countXmlUrl++;

                realXmlUrl = xmlUrl[countXmlUrl];
                this.request_xml();
            }
            if (http_request.status == 200)
            {
                xmlDoc = http_request.responseXML;
                alert("need to update3");
                this.peter_save_data();
            }

        }
    },

    peter_save_data:function()
    {
      // removed function code
    }

});
var X = new T();//etc etc


来源:https://stackoverflow.com/questions/6317845/javascript-is-not-a-function-error-when-calling-defined-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!