Javascript对象和this关键字

Javascript对象和this关键字,javascript,class,object,this,Javascript,Class,Object,This,我知道这是对对象所有者的引用。但我很难让一个类工作起来,同时也很难确定它所指的是什么 我想最好只显示代码: function Ajax_Class(params) { // Public Properties this.Response = null; // Private Properties var RequestObj = null; // Prototype Methods this.OnReset = function() { }; this.OnOpenConn = fun

我知道这是对对象所有者的引用。但我很难让一个类工作起来,同时也很难确定它所指的是什么

我想最好只显示代码:

function Ajax_Class(params) {
// Public Properties
this.Response = null;

// Private Properties
var RequestObj = null;

// Prototype Methods
this.OnReset    = function() { };
this.OnOpenConn = function() { };
this.OnDataSent = function() { };
this.OnLoading  = function() { };
this.OnSuccess  = function() { alert("default onSuccess method."); };
this.OnFailure  = function() { alert("default onFailure method."); };

// Public Methods
this.Close = function() {   // Abort current Request
    if (RequestObj) {
        RequestObj.abort();
        RequestObj = null;
        return true;
    } else return false;
};

// Private Methods
var Instance = function() {     // To create instance of Http Request
    try { return new XMLHttpRequest(); }
    catch (error) {}
    try { return new ActiveXObject("Msxml2.XMLHTTP"); }
    catch (error) {}
    try { return new ActiveXObject("Microsoft.XMLHTTP"); }
    catch (error) {}

    // throw new Error("Could not create HTTP request object.");
    return false;
};

var ReadyStateHandler = function() {
    // Switch through possible results
    switch(RequestObj.readyState) {
        case 0:
            this.OnReset();
        break;

        case 1:
            this.OnOpenConn();
        break;

        case 2:
            this.OnDataSent();
        break;

        case 3:
            this.OnLoading();
        break;

        case 4:
            // Check Status
            if (RequestObj.status == 200)  {
                // Handle Response
                Response = HandleResponse();
                // Call On Success
                this.OnSuccess();
                // Hide Loading Div
                LoadingDiv(true);
            } else {
                this.OnFailure();
            }

        break;
    } // End Switch
};

var Open = function() {
    // In case it's XML, Override the Mime Type
    if ((params["ResponseType"] == "XML") && (RequestObj.overrideMimeType)) 
        RequestObj.overrideMimeType('text/xml');

    // 
    if ((params["User"]) && (params["Password"]))
        RequestObj.open(params["Method"], params["URL"],  params["Async"], params["User"], params["Password"]);
    else if (params["User"])
        RequestObj.open(params["Method"], params["URL"],  params["Async"], params["User"]);
    else
        RequestObj.open(params["Method"], params["URL"],  params["Async"]);

    // Set Request Header ?
    if (params["method"] == "POST") 
        //this.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        RequestObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

};

var Send = function() {
    if (params["Data"])     RequestObj.send(params["Data"]);
    else                    RequestObj.send(null);
};

var HandleResponse = function() {
    if (params["ResponseType"] == "JSON")
        return ParseJSON(RequestObj.responseText);
    else if (params["ResponseType"] == "XML")
        return RequestObj.responseXML;
    else 
        return RequestObj.responseText;
};

// Method ParseJSON
var ParseJSON = function(obj) {
    if (obj)
        return JSON.parse(obj);
}; // End ParseJSON

// Method LoadingDiv -> Either Shows or Hides the Loading Div
var LoadingDiv = function(hide) {
    // Hide the Modal Window
    if (hide) { document.getElementById("Async").style.display = "none"; return false; }

    // Show Modal Window
    document.getElementById("Async").style.display = "block";

    // Reset the Position of the Modal_Content to 0, x and y
    document.getElementById("Async_Container").style.left = "0px";
    document.getElementById("Async_Container").style.top = "0px";

    // Center the Modal Area, no matter what the content
    var Screen_Width, Screen_Height;
        // Get screen data
        if (typeof(window.innerWidth) == "number") { Screen_Width = window.innerWidth; Screen_Height = window.innerHeight; }            //Non-IE
        else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {         //IE 6+ in 'standards compliant mode'
            Screen_Width = document.documentElement.clientWidth;
            Screen_Height = document.documentElement.clientHeight;
        } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {                                        //IE 4 compatible
            Screen_Width = document.body.clientWidth;
            Screen_Height = document.body.clientHeight;
        }

        // Set Modal_Content Max Height to allow overflow
        document.getElementById("Async_Container").style.maxHeight = Screen_Height - 200 + "px";

        // Get Modal_Container data
        var El_Width = document.getElementById("Async_Container").offsetWidth;
        var El_Height = document.getElementById("Async_Container").offsetHeight;


    // Set the Position of the Modal_Content
    document.getElementById("Async_Container").style.left = ((Screen_Width/2) - (El_Width/2)) + "px";
    document.getElementById("Async_Container").style.top = ((Screen_Height/2) - (El_Height/2)) + "px";
};


// Constructor

// Check the Params
// Required Params
if (!params["URL"]) return false;
// Default Params
params["Method"]        = (!params["Method"]) ? "GET" : params["Method"];   // GET, POST, PUT, PROPFIND
params["Async"]         = (params["Async"] === false) ? false : true;
params["ResponseType"]  = (!params["ResponseType"]) ? "JSON" : params["ResponseType"];  // JSON, TXT, XML
params["Loading"]       = (params["Loading"] === false) ? false : true;
// Optional Params
// params["User"])
// params["Password"]

// Create Instance of Http Request Object
RequestObj = Instance();

// Handle Ajax according to Async
if (params["Async"]) {
    // Handle what should be done in case readyState changes
    if (params["Loading"]) LoadingDiv();
    // State Handler || Response is Handled within the code
    RequestObj.onreadystatechange = ReadyStateHandler;
    // Open & Send
    Open();
    Send();
} else {
    // Handle the Loading Div
    if (params["Loading"]) LoadingDiv();
    // Open & Send
    Open();
    Send();
    // Handle Response
    this.Response = HandleResponse();
    // No State Handler, Application has been waiting for modifications.
    //this.OnSuccess(Response);
    // Handle the Loading Div
    LoadingDiv(true);
}

// no problems?
return true;

} // End Ajax
然后,在页面内部:

window.onload = function() {

update_states = function() {
    this.OnSuccess = function() {
        alert("overriden onSuccess Method");
    };
};
    update_states.prototype = new Ajax_Class({URL:"ajax/states.php?id=5&seed="+Math.random()});
    run_update_states = new update_states;      

} // Window Onload
我试图做的是有一个默认的OnSuccess(等)方法,如果需要,我可以用子类方法覆盖默认方法,但它仍然会在HttpRequest状态更改时自动调用

如果有人能给我指出正确的方向,我将不胜感激,如果我能理解为什么在这种情况下这不起作用,以及如何使它指向正确的对象,我将感到惊讶


感谢您的帮助。

是根据调用某物的方式设置的。以下是不同的设置方式:

  • func()
    -正常的函数调用<代码>此设置为全局对象(
    浏览器中的窗口

  • obj.method()
    -方法调用<代码>此设置为
    obj

  • 函数调用(obj,arg1,arg2,…)
    -使用
    .call()
    <代码>此设置为
    obj

  • func.apply(对象、参数)
    -使用
    .apply()
    <代码>此设置为
    obj

  • 函数绑定(obj,arg1,arg2,…)
    -使用
    .bind()
    。创建一个新函数,该函数在调用时将
    this
    设置为
    obj
    (在内部,它在实现中使用
    .apply()

  • 要注意的典型事情

    • 即使从对象的方法中调用常规函数,也会导致
      this
      指针位于该函数中的
      window
    • 回调函数通常会收到一个与它可能嵌入的代码不同的
      值。您可能需要将原始的
      值保存到一个局部变量中(通常按惯例称为
      self
      ),以便从回调函数中引用它
    你试过这个吗

    run_update_states = new update_states();
    

    请注意括号。

    也许您正在尝试执行以下操作:

    function Base() {}
    
    Base.prototype.showName = function() {
      alert('Base method: ' + this.name);
    }
    
    function Foo(name, arg){
    
       this.name = name;
    
      // Extend this if arg is an object
      if (typeof arg == 'object') {
        for (var p in arg) {
    
          // This references the new instance if called with new keyword
          if (arg.hasOwnProperty(p)) {
            this[p] = arg[p];
          }
        }
      }
    }
    
    Foo.prototype = new Base();
    
    // Re-assign constructor property (not very useful but some to do like this)
    Foo.prototype.constructor = Foo; 
    
    var inst0 = new Foo('foo 0');
    
    // Override inherited method
    var inst1 = new Foo(
                 'foo 1',
                 {showName: function(){alert('Instance method: ' + this.name);}}
                );
    
    inst0.showName(); // Base method: foo 0
    inst1.showName(); // Instance method: foo 1
    

    但还有其他(更简单?更好?)的方法。让原型继承和javascript的动态特性为您所用,不要仅仅因为您对其他继承模式比较熟悉就试图让它模拟它们。

    console.log(此)
    在Firefox或Chrome中有助于确定此
    在代码的特定部分(范围)中指的是什么。另外,
    不是对象所有者,而是对象本身。另一个方便的技巧是使用
    typeof(this)
    this.constructor
    来获取有关对象的更多信息。我明白了。如果指向对象xmlHttpRequest,则this.OnSuccess就是这样。根据你所说的,这是有道理的。但是当我在类块上尝试时,类似于:var self=this;然后我无法重写类方法,因为它总是引用主类。这有什么意义吗?我按照Jfriend00说的做了:函数Ajax_Class(){var self=this;(…)然后尝试,在状态更改时:self.OnSuccess();然后它将始终调用默认的类OnSuccess函数,而不是我在子类上设置的函数……我很高兴您解决了它。对于原型和范围解析,请尝试这个。“对象上属性名称的解析"节。@MalSu-
    与作用域无关,它们是完全不同的东西。在ES5严格模式下,
    可以是任何东西,甚至是
    未定义的
    空的
    。尽管引用了Richard Cornford,但还是值得称赞的。请注意,
    调用
    应用
    ,以及最近的
    绑定
    ,都可以l将
    的上下文更改为您想要的任何内容,后者在不执行函数的情况下执行。@leemachin-我添加了
    .bind()
    -已经有
    .call()
    .apply()
    。我很感激你的回答。但实际上,这让我很困惑。那么,当我创建一个对象的新实例时,这种行为的预期行为是什么?@IgorDonin-你的问题只有需要回答的信息的1/3。如果你创建一个名为
    myObject
    的新对象,并使用
    myObject.print()对该对象调用一个方法
    ,则该
    将在该特定调用的
    print()
    方法中设置为
    myObject
    。如果您有不同的对象
    yourObject
    并调用
    yourObject.print()
    ,然后
    这个
    将被设置为
    你的对象
    ,在
    打印
    方法的特定执行中。调用方决定如何设置这个
    。我的问题是整个类和对象实例化。都在那里,伙计。update_state是一个使用Ajax_类作为原型和对象的类有一个OnSuccess方法覆盖原型的方法。run_update_state创建一个update_state实例,该实例获取http请求的响应并进行处理。我想要的是运行update_state的OnSuccess方法,而不是原型的方法。谢谢你的回答,伙计。我测试了它,但没有成功。预期的结果是什么n您创建了一个对象的实例,同时运行了一个函数?对象是否运行?是否创建了更新状态?如果这对您的脚本来说不是问题,您可以将您需要的函数
    onSuccesss
    作为参数传递给
    AjaxClass
    ,并将其添加到对象(如果存在)。我花了一段时间才看到y的智慧我们的答案。干杯,伙计。