簡體   English   中英

JavaScript遞歸回調函數-ReferenceError:未定義函數

[英]JavaScript Recursive Callback Function - ReferenceError: function is not defined

我的想法是顯示陣列中的所有圖像。 首先,Noise圖像在此之后被隱藏,它調用showArray()函數以顯示Array中的圖像。

Trial = (function() {
  function Trial(imageArray) {
    this._images = new Array();
    this._images = imageArray;
  }

  Trial.prototype.startTrial = function() {
    return $("#noise").hide(0, showImages());
  };

  Trial.prototype.showImages = function() {
    var imageToShow;
    imageToShow = this._images.pop();
    if (imageToShow === void 0) {
      $("#noise").show;
      return;
    }
    $("#img").attr("src", imageToShow.src);
    return $("#img").fadeIn(0).delay(imageToShow.delay).fadeOut(0, showImages());
  };

  return Trial;

})();

image1 = new AMPImage("someImage1.png", 500);  //imagePath, delay in ms
image2 = new AMPImage("someImage2.png", 750);
image3 = new AMPImage("someImage3.png", 1000);

myImageArray = [image1, image2, image3];
trial1 = new Trial(myImageArray);
trial1.startTrial();

但是在執行startTrial()時,我收到錯誤消息

ReferenceError:showArray未定義

根據您的最新編輯:

上下文不是那樣工作的。 showImages不是變量。 這是Trial類的原型上的一種方法。 如果要從外部代碼調用它,可以執行以下操作:

myTrial.showImages();

如果要從Trial類中的另一個方法調用它,則必須在當前實例上將其作為方法調用。 您可以像this獲得對當前實例的引用。

this.showImages();

代替

showImages();

但是,您實際上不希望立即調用該函數,而是希望動畫結束后立即調用該函數。 為此,請將函數作為值傳遞給animation方法。 只需省略() ,您將傳遞該函數。

問題在於, this上下文是一個善變的野獸,如果這樣做,將是不正確的。 要保持正確的this背景下,你必須將它綁定:

var showImagesToCallLater = this.showImages.bind(this);

// some time later, perhaps inside another method you can then do:

showImagesToCallLater();

// and this will have the correct `this` context.

因此,對於我們的示例,我們需要.hide(0, this.showImages.bind(this)); .fadeOut(0, this.showImages.bind(this));

附加代碼審查

我已經檢查了其余代碼,並建議您可能要進行的其他更改。 如果您只是想讓代碼盡快運行,則可以忽略以下內容:

// There's no need to create an extra closure here,
// we can remove a level of nesting.
function Trial(imageArray) {
  // There's no point writing to `this._images` then immediately
  // overwriting, so we only write to it once here
  this._images = imageArray;
}

Trial.prototype.startTrial = function() {
  // I assume you want to begin showing images once #noise is hidden.
  // To do this, pass a function to hide.
  return $("#noise").hide(0, this.showImages.bind(this));
};

Trial.prototype.showImages = function () {
  var imageToShow;
  imageToShow = this._images.pop();
  if (imageToShow === void 0) {
    // You need to actually call this function
    $("#noise").show();
    return;
  }
  $("#img").attr("src", imageToShow.src);
  // Once one image has been shown, I'm guessing you want to show the next.
  // to do this, we `.bind` the function so it has the correct `this` value.
  return $("#img").fadeIn(0).delay(imageToShow.delay)
                  .fadeOut(0, this.showImages.bind(this));
};

image1 = new AMPImage("someImage1.png", 500);  //imagePath, delay in ms
image2 = new AMPImage("someImage2.png", 750);
image3 = new AMPImage("someImage3.png", 1000);

myImageArray = [image1, image2, image3];
trial1 = new Trial(myImageArray);
trial1.startTrial();

您希望它在動畫完成后執行,而不是調用使函數立即執行的函數。 為此,您需要傳遞實際的函數,因此在函數上調用.bind(this) 這樣,它將在正確的上下文中執行。

您可以選擇為此構建一個更具“功能性”的版本:

function startTrial(imageArray) {
  // note how we pass the function showImage, we don't call it
  $("#noise").hide(0, showImage);
  function showImage() {
    var imageToShow = imageArray.pop();
    if (imageToShow === undefined) {
      $("#noise").show();
      return;
    }
    $("#img").attr("src", imageToShow.src);
    return $("#img").fadeIn(0).delay(imageToShow.delay).fadeOut(0, showImage);
  }
}
var image1 = new AMPImage("someImage1.png", 500);  //imagePath, delay in ms
var image2 = new AMPImage("someImage2.png", 750);
var image3 = new AMPImage("someImage3.png", 1000);

var myImageArray = [image1, image2, image3];
startTrial(myImageArray);

您更喜歡哪種風格取決於個人喜好。 功能版本使您無需考慮所有this綁定行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM