2012-09-06 48 views
0

我知道这个对对象所有者的引用。但我很难尝试上课,同时试图确定这个所引用的内容。Javascript对象和这个关键字

想这是最好只显示代码:

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状态更改时它仍会自动调用。

我很感激,如果有人能指出我在正确的方向,并会惊讶,如果我能明白为什么这不在这个circunstance工作,以及如何使其参考正确的对象。

感谢您的任何帮助。

+0

Firefox或Chrome中的'console.log(this)'有助于确定代码(范围)中某些部分所指的是什么。另外,'this'不是对象所有者,它是对象本身。另一个方便的提示是使用'typeof(this)'或'this.constructor'来获取对象的更多信息。 – MalSu

+0

我明白了。它的方式是this.OnSuccess,如果指向对象xmlHttpRequest。基于你所说的话是有道理的。但是,当我尝试,而在类块,如下所示:var self = this;那么我无法重写类方法,因为它总是指的是主类。这有任何意义吗? –

+0

呵呵,不是太多... – MalSu

回答

1

this根据如何调用。这些都是不同的方式将其设置:

  1. func() - 一个普通的函数调用。将this设置为全局对象(在浏览器中为window)。

  2. obj.method() - 方法调用。 this设置为obj

  3. func.call(obj, arg1, arg2, ...) - 使用.call()this设置为obj。使用.apply()this设置为obj

  4. func.bind(obj, arg1, arg2, ...) - 使用.bind()。创建一个新函数,该函数在调用时设置thisobj(内部地,它在其实现中使用.apply())。

典型的值得注意的事情。

  • 调用一个常规功能,即使从一个对象的方法中会导致this指针为window该函数内部。
  • 回调函数通常会收到与其可能嵌入的代码不同的this值。您可能必须将原始this值保存到本地变量中(通常按惯例称为self),以便您可以从您的回调函数。
+0

请注意,'call','apply'和最近的'bind'都可以将'this'的上下文更改为任何你想要的内容,后者不需要执行该功能。 – mrlee

+0

@leemachin - 我添加了'.bind()' - 已经有'.call()'和'.apply()'。 – jfriend00

+0

我很感谢你的回答。但实际上,这让我感到困惑。那么,当我创建一个对象的新实例时,这是什么预期的行为? –

0

你尝试过这个

run_update_states = new update_states(); 

通知括号。

+0

感谢您的回答,队友。我测试了它,但没有去。创建对象实例并同时运行函数时,预期的结果是什么?对象run_update_states是否被创建? –

+0

yes对象被创建 – zeacuss

+0

如果这对脚本没有问题,您可以将需要'onSuccesss'的函数作为参数传递给'AjaxClass',并将其添加到对象中(如果存在)。 – zeacuss

1

也许你正在尝试做的是这样的:

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的动态特性为你工作,不要试图让它模仿其他继承模式,只是因为你更适应它们。

+0

我花了一段时间才看到答案中的智慧。队友的欢呼声。 –