Специфическая проблема с закрытием / ограничением области в jQuery

#jquery #closures

#jquery #закрытия

Вопрос:

Я так часто сталкиваюсь с этим шаблоном.
Может кто-нибудь, пожалуйста, дать мне канонический способ получения image1 только один раз — если вы посмотрите на второй пример, это работает — но я не понимаю, почему. Объяснение этой конкретной ситуации приветствуется, я прочитал материал о закрытии в сети 🙂

Исходный код:

 $(document).ready(function() {
  $("#prev, #next").click(function() {
    var mainImage = $("#image1");
    if (mainImage.css("visibility")=="hidden") {
      $(mainImage.css("visibility","visible");
      return;
    }
    var currentNumber = parseInt(mainImage.attr("src").split('gallery/')[1]); 
    var newNumber = ($(this).attr("id")=="next")?currentNumber 1:currentNumber-1;
    var testImage = new Image();
    testImage.onload=function() {
      var img = $("#image1");
      img.attr("src",this.src);
      img.css("visibility","visible");   
    }
    testImage.onerror=function() {
      $("#image1").css("visibility","hidden");   
    }
    testImage.src="gallery/" newNumber ".jpg";
    return false;
  });
});
  

Попытка закрытия — почему это работает — или это просто проблема с областью действия?

 $(document).ready(function() {
  $("#prev, #next").click(function() {
    var mainImage = $("#image1"); // this should be local to the click function
    if (mainImage.css("visibility")=="hidden") {
      $(mainImage.css("visibility","visible");
      return;
    }
    var currentNumber = parseInt(mainImage.attr("src").split('gallery/')[1]); 
    var newNumber = ($(this).attr("id")=="next")?currentNumber 1:currentNumber-1;
    var testImage = new Image();
    testImage.onload=function() {
      mainImage.attr("src",this.src); // how come mainImage is available here?
      mainImage.css("visibility","visible");   
    }
    testImage.onerror=function() {
      mainImage.css("visibility","hidden");// how come mainImage is available here?
    }
    testImage.src="gallery/" newNumber ".jpg";
    return false;
  });
});
  

Ответ №1:

В javascript переменные находятся в области действия функции, в которой она была определена, и «подфункциях» (локальных функциях) внутри этой функции.

Например:

 function fun1(){
   var var1 = "Defined in fun1. ";
   function fun2(){
      var var2 = "Defined in fun2. ";
      alert(var1); //Alerts "Defined in fun1 "
      function fun3(){
          alert(var1   var2); //Alerts "Defined in fun1. Defined in fun2";
      }
   }
   alert(var2); //Alerts 'undefined' (fun1 doesn't know var2 exists)
}
  

И то же самое происходит в вашем коде. Ваша переменная mainImage «живет» в каждой локальной функции. Не забывайте, что привязанные функции также являются локальными функциями, даже если у них нет имени или они объявлены по-другому.

Надеюсь, это поможет. Приветствия

Комментарии:

1. Это одни и те же клоуны с разными никами, хе-хе

Ответ №2:

Вот как работает область видимости JavaScript. Взгляните на следующее:

 var func1 = function(){
    console.log(i   2);
};

var myFunc = function(){
    var i = 1;
    var func2 = function(){
        console.log(i   2);
    };
    func2(); // output 3
    func1(); // ReferenceError: i is not defined
};
  

Ответ №3:

MainImage определяется с помощью var, поэтому он становится глобальным для всех функций

Комментарии:

1. ??? если я НЕ использую var, он становится глобальным Windows var. но С var она обычно остается локальной для функции, в которой она определена