2010-06-10 108 views
1

我想弄清楚綁定函數原型的正確位置,以後再調用。該示例的完整的代碼可以在這裏找到:函數原型定義裏面的Javascript對象綁定問題

http://www.iprosites.com/jso/

我的JavaScript的例子是非常基本的:

function Obj(width, height){ 
    this.width = width; 
    this.height = height; 
} 

Obj.prototype.test = function(){ 
    var xhr=init(); 
    xhr.open('GET', '?ajax=test', true); 
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); 
    xhr.onreadystatechange = function() { 
     if (xhr.responseText == '403') { 
      window.location.reload(false); 
     } 
     if (xhr.readyState == 4 && xhr.status == 200) { 
      this.response = parseResponse(xhr.responseText); 
      document.getElementById('resp').innerHTML = this.response.return_value; 
      this.doAnotherAction(); 
     } 
    }; 
    xhr.send(); 
} 

Obj.prototype.doAnotherAction = function(){ 
    alert('Another Action Done'); 
} 


var myo = new Obj(4, 6); 

如果您嘗試運行myo.test()在Firebug,你會得到「this.doAnotherAction不是一個函數」的迴應。如果你想查看它們,那麼2個支持函數init()和parseResponse()可以在test.js鏈接中找到,但不應該與這個問題太相關。我已經肯定this.doAnotherAction()認爲「this」是XMLHttpResponse對象,正如預期的instanceof測試一樣。

任何人都可以幫助一些有約束力的方向?我試過的所有東西似乎都不起作用!

我確實使用Mootools,雖然在本例中該庫不存在。

由於提前,

阿里昂

回答

1

thisxhr.onreadystatechange裏面並不是指的Obj實例。您需要在局部變量中捕獲函數外部的this,然後使用xhr.onreadystatechange的內部變量。即

Obj.prototype.test = function(){ 
    var obj = this, 
     xhr=init(); 
    xhr.open('GET', '?ajax=test', true); 
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); 
    xhr.onreadystatechange = function() { 
     if (xhr.responseText == '403') { 
      window.location.reload(false); 
     } 
     if (xhr.readyState == 4 && xhr.status == 200) { 
      this.response = parseResponse(xhr.responseText); 
      document.getElementById('resp').innerHTML = this.response.return_value; 
      obj.doAnotherAction(); 
     } 
    }; 
    xhr.send(); 
} 

粘貼到上述控制檯,然後運行myo.test() :)

+0

很好的一把槍的兒子,當我這樣做的時候它確實有效。雖然爲了避免正確使用函數綁定,它似乎有點偷工減料,不是嗎?我很感謝你提供了一個可行的答案,但是對於這種情況下綁定的性質有任何想法是偶然的嗎?萬分感謝!!! :) – Arion 2010-06-10 22:42:46

+0

你的意思是正確使用函數綁定?分配給'onreadystatechange'(即'this')的匿名函數中的函數上下文是'xmlHttpRequest'對象。如果不將該函數與「Obj」實例的上下文一起使用(就像Anurag的回答中那樣),我認爲不會有這種情況。所以你需要捕獲變量中的外部上下文,並在內部函數中使用該變量。 – 2010-06-11 07:36:34

1

ECMAScript的第5版在測試頁上測試此。已經從Prototype框架中借用了bind方法。你可以將它包含在你的代碼中,如果它不存在,它將定義一個綁定方法。

if (!Function.prototype.bind) 
{ 
    Function.prototype.bind = function() { 
     var fn = this, 
      args = Array.prototype.slice.call(arguments), 
      object = args.shift(); 

     return function() { 
      return fn.apply(object, 
       args.concat(Array.prototype.slice.call(arguments))); 
     }; 
    }; 
} 

定義之後,可以綁定onreadystatechange回調與obj的對象內部的匿名函數。

xhr.onreadystatechange = function() { 
    ... 
}.bind(this); 
+0

ahhh好所以我之前的問題是我試圖添加bind(this)到test()或doAnotherAction()方法,當我應該已經將「this」綁定到onreadystatechange回調。 – Arion 2010-06-11 16:40:22