2013-05-16 173 views
0

內部調用函數我有這樣的代碼:的Javascript模塊模式:嵌套函數

var SEVERINU = SEVERINU || {}; 

SEVERINU.AutoGallery = { 
    galleryImagesNames: new Array(), 

    findImages: function() { 
     var dirToResearch = this.galleryName; 

     $.post(
      "_php/get-files.php", { 
      dir: dirToResearch, 
      ext: this.fileExtension 
     }, function (data) { 
      var pliki = $.parseJSON(data); 
      console.log(data); 
      for (var i in pliki) { 
       this.galleryImagesNames.push(pliki[i]); // problem ! 
      } 
     }); 

    }, 
} 

這條線:this.galleryImagesNames.push(pliki[i]);是給我的問題。

它說,他不能發現變種galleryImagesNames等

如何調用函數,VAR如果我要「深」?

+1

上下文('this')已經改變,'this'不再是你認爲它在回調中的東西。 –

+0

如何調用galleryImagesNames? – user2391064

+0

查看任何現有的答案。 –

回答

3

只需將當前的this保存到某個其他變量中,以便它不會在函數內部被覆蓋。

var SEVERINU = SEVERINU || {}; 

SEVERINU.AutoGallery = { 
    galleryImagesNames : new Array(), 

    findImages : function(){ 
     var self = this; // keep current value of this in variable named self 
     var dirToResearch = this.galleryName; 

     $.post(
      "_php/get-files.php", 
      { 
       dir: dirToResearch, 
       ext: this.fileExtension 
      }, 
      function(data){ 
       var pliki = $.parseJSON(data); 
       console.log(data); 
       for(var i in pliki){ 
        // call the method using self variable instead of this that got overwritten 
        self.galleryImagesNames.push(pliki[i]); 
       } 
      } 
     ); 

    }, 

} 
1

其實那是因爲你的$.post有不同的範圍比對象的其餘部分。試試這個:

findImages : function(){ 
    var dirToResearch = this.galleryName; 
    var gImageNames = this.galleryImagesNames; 
    $.post(
     "_php/get-files.php", 
     { 
      dir: dirToResearch, 
      ext: this.fileExtension 
     }, 
     function(data){ 
      var pliki = $.parseJSON(data); 
      console.log(data); 
      for(var i in pliki){ 
       gImageNames.push(pliki[i]); // we have access to this variable 
      } 
     } 
    ); 

}, 
+0

它返回空數組。數組看起來很好,直到$ .post之內,之後......它完全是空的。你能告訴我爲什麼嗎 ? – user2391064

1

既然你是一個匿名函數裏面,你會不得不再次引用this關鍵字。或者直接使用它像這樣:

SEVERINU.AutoGallery.galleryImagesNames.push(pliki[i]); 

通常當你需要不止一次你更好地將其存儲在像變量參考SEVERINU.AutoGallery

var that = SEVERINU.AutoGallery; // or "self" or something you prefer 

for (var i in pliki) { 
    that.galleryImagesNames.push(pliki[i]); 
} 

這樣做的原因是因爲JavaScript趨於訪問對象命名空間時速度慢。你走的越深,它越慢。由於函數作用域必須首先解析才能訪問下一個/上一個作用域,因此您創建的引用越多,它將變得越慢。

+0

這一個爲我工作,但想用這個,以防有人將部分SEVERINU.Autogallery改爲別的東西。謝謝 – user2391064

+0

特別是在你的for循環中,你可以像對象的長度一樣訪問'SEVERINU.AutoGallery'多次。當存儲在變量中時,它將被引用並且性能更高。例如,jQuery選擇器也是如此。 –

1

您還可以使用$.proxy傳遞上下文。

var SEVERINU = SEVERINU || {}; 

SEVERINU.AutoGallery = { 
galleryImagesNames : new Array(), 

findImages : function(){ 
    var dirToResearch = this.galleryName; 

    $.post(
     "_php/get-files.php", 
     { 
      dir: dirToResearch, 
      ext: this.fileExtension 
     }, 
     $.proxy(function(data){ //Set up for the context to be passes for this function. 
      var pliki = $.parseJSON(data); 
      console.log(data); 
      for(var i in pliki){ 
       this.galleryImagesNames.push(pliki[i]); // problem solved. now this doesn't refer to ajax context 
      } 
     },this) <-- Pass the context here 
    ); 

}, 
} 

$ .proxy接受一個函數,並返回一個新的,總會有一個特定的背景。

+0

@downvoter,爲什麼..這只是另一種選擇。小心解釋.. – PSL