2012-09-12 76 views
0

我遇到了使用內部函數函數的問題。javascript內部函數問題

this.init = function() { 

    var size = this.ref; 
    var wall = this.element; 
    var id = this.id; 
    var initRef = this.init; 

    this.update(id, size, wall, initRef); 
} 


this.update = function (id, size, wall, init) { 

    $.get(url, "cpart=" + id + "&ref=" + size, (function (wall, size, init) { 
    return function (data) { 
     if (data) { 
     var response = JSON.parse(data); 
     size = response["psize"]; 
     wall.append(response["msg"]); 
     wall.scrollTop($(document).height()); 
     } 

     init(); 
    } 
    })(wall, size, init)); 
} 

我遇到的問題是第二次迭代,在Ajax請求的變量是不確定的,我不知道爲什麼發生這種情況。當第一次調用函數時,第二次調用函數時,變量和大小是未定義的。

感謝提前

+1

有在更新功能沒有參數的 「URL」?這是全球性宣佈的嗎? –

+0

是的,它是全局聲明的 – CBaker

+0

這不是一個很好的使用匿名函數和自我調用函數。你讓它過於複雜 – Ibu

回答

0

幫助我猜格式的你的說法應該是這樣的:

$.get(url, {cpart: id, ref: size}, (function (wall, size, init) { 
    // existing stuff 
}); 

希望這會有所幫助。

0

嘗試代替:

this.update = function (id, size, wall, init) { 

    $.get(url, "cpart=" + id + "&ref=" + size, (function (self, wall, size, init) { 
     return function (data) { 
      if (data) { 
       var response = JSON.parse(data); 
       size = response["psize"]; 
       wall.append(response["msg"]); 
       wall.scrollTop($(document).height()); 
      } 

      init.apply(self); 
     } 
    })(this, wall, size, init)); 
} 

既然你沒有真正指定激活對象,什麼都可能會發生在調用init。


更新: 現在我有更多的關注閱讀你的代碼。

雖然,我並不完全確定你想達到什麼樣的,這裏有一個修訂版:

this.update = function() { 
    var self = this; 

    $.get(url, "cpart=" + id + "&ref=" + size, function(data) { 
     if (data) { 
      var response = JSON.parse(data); 
      self.size = response["psize"]; 
      self.wall.append(response["msg"]); 
      self.wall.scrollTop($(document).height()); 
     } 

     init.call(self); 
    }); 
} 

請注意,我不再傳遞參數給update,而是我直接使用對象的屬性。我在self變量中保留了一個對象的引用,這個變量可以從我們給$.get()的匿名函數訪問,因爲它是在圍繞它的函數中聲明的(即「更新」函數)。


更新2

你調用初始化,要求更新,這將導致在初始化再次呼籲!你不覺得應該有辦法打破這個循環嗎?
你會錘擊服務器和用戶的瀏覽器。

我認爲這是最好的,如果你只是告訴我們你想達到什麼目的。


更新3

感覺就像我做你的工作你:J-

// If you're writing a "class", there's got 
// to be a constructor somewhere: 

function YourClass(id, ref, element) { 
    // These need to come from somewhere... 
    this.id = id; 
    this.ref = ref; 
    this.element = element; 
} 


// Now we set your "class methods" on YourClass.prototype, 
// so they can be shared among all the instances of YourClass. 
// Create instances like this: 
// obj = new YourClass(); 

YourClass.prototype.init = function() { 
    // You want to give these properties 
    // alternate names, I'll respect that. 
    // (notice obj.ref won't ever be updated, but obj.size will) 
    this.size = this.ref; 
    this.wall = this.element; 
    this.update(); 
} 


YourClass.prototype.updateFromData = function(data) { 
    // I moved this code to a helper "class method" to make things more clear 
    if (data) { 
     var response = JSON.parse(data); 
     this.size = response["psize"]; 
     this.wall.append(response["msg"]); 
     obj.wall.scrollTop($(document).height()); 
    } 
    this.init(); 
} 


YourClass.prototype.update = function() { 
    // Not the most elegant way of coding this, 
    // but it should be easier to read.   
    function createUpdater(obj){ 
     return function(data){ 
      obj.updateFromData(data); 
     } 
    }   
    $.get(url, "cpart=" + this.id + "&ref=" + this.size, createUpdater(this));   
} 

// An alternative to the above would simply be this: 
// YourClass.prototype.update = function() { 
//  $.get(url, "cpart=" + this.id + "&ref=" + this.size, this.updateFromData.bind(this)); 
// } 
+0

我試過了,我得到了同樣的結果。im試圖通過ajax請求的返回函數傳遞所有這些的原因是因爲你不能使用「this」引用變量。所以我使用init函數來獲取對它們的引用,然後傳遞函數中的變量,但我明顯錯過了某些 – CBaker

+0

可以用'that'來解決這個問題嗎?把'that = this'放在外部函數中,然後'init.apply(that)' –

+0

@mashit無論你想要什麼(只要它不是保留字),都可以命名這個變量。 「那」完全可以接受。 – Zecc