Как правильно понять этот код? [закрыто]

229
15 декабря 2016, 16:21

Так как JavaScript занимаюсь всего месяц, я еще не очень освоил детали. Нужно разъяснение по работе кода. А именно - что происходит в каждой строчке кода:

function preloadImages() {
    if (typeof arguments[arguments.length - 1] == 'function') {
        var callback = arguments[arguments.length - 1];
        } else {
            var callback = false;
        }
         if (typeof arguments[0] == 'object') {
          var images = arguments[0];
           var n = images.length;
       } else {
          var images = arguments;
          var n = images.length - 1;
       }
       var not_loaded = n;
       for (var i = 0; i < n; i++) {
         jQuery(new Image()).attr('src', images[i]).load(function() {
             if (--not_loaded < 1 && typeof callback == 'function') {
                callback();
            }
        });
    }
}
Answer 1

Комментарии к коду:

function preloadImages() {
    //
    //Смотрим была ли передана функция callback последним параметром
    //preloadImages(function(){})
    //
    if (typeof arguments[arguments.length - 1] == 'function') {
        var callback = arguments[arguments.length - 1];
    } else {
        var callback = false;
    }
    //
    //Проверяем как были переданы пути картинок
    //массивом: preloadImages(["a.jpg", "b.jpg"])
    //или через запятую: preloadImages("a.jpg", "b.jpg")
    //
    if (typeof arguments[0] == 'object') {
        var images = arguments[0];
        var n = images.length;
    } else {
        var images = arguments;
        var n = images.length - 1;
    }
    var not_loaded = n;
    //
    //Создаем новый объект класса Image
    //Устанавливаем поле src - путь к картинке
    //Подписываемся на событие load
    //Если была задана callback-функция, вызываем ее
    //
    for (var i = 0; i < n; i++) {
        jQuery(new Image()).attr('src', images[i]).load(function() {
            if (--not_loaded < 1 && typeof callback == 'function') {
                callback();
            }
        });
    }
}

Можно сделать проще и красивее:

function preload(sources)
{
    var images = [];
    for (i = 0, length = sources.length; i < length; ++i) {
        images[i] = new Image();
        images[i].src = sources[i];
    }
}

или

$.fn.preload = function() {
    this.each(function(){
        $('<img/>')[0].src = this;
    });
}

Взято отсюда тут и тут.

Answer 2

Это имитация перегрузки функции:

preloadImages([url1, url2, ...]);
preloadImages([url1, url2, ...], callback);
preloadImages(url1, url2, ..., callback);
// preloadImages(url1, url2, ...); // Потеряли из-за бага

Сама функция загружает все картинки и вызывает коллбек, если он был предоставлен.

  • Если последним параметром передана функция, то это callback. Иначе коллбека нет.
  • Если первым параметром передан объект, то мы считаем, что это images - массив с изображениями.
  • Если первым параметром передан не объект, то мы ожидаем вызов в стиле preloadImages(url1, url2, ..., callback) и вытаскиваем images как все arguments кроме последнего. Не совсем так, но такое поведение эмулируется за счёт использования n вместо длины. Это баг! Нельзя передать поштучно адреса, не передав коллбек - последний адрес потеряется.
  • Загружаем поштучко картинки. При загрузке уменьшаем not_loaded - число картинок, которые осталось загрузить.
  • Если загрузились все картинки и есть коллбек, то вызываем его.

PS: Функция не очень хорошо написана, постоянное объявление одних и тех же переменных раздражает. Неиспользование условного оператора - тоже. Ну и проверка typeof в конце, хотя там гарантированно либо функция, либо false.

READ ALSO
Парсинг текста HTML с помощью jsoup

Парсинг текста HTML с помощью jsoup

Нужно вытащить текст "Количество помещений (зданий) - всего, единиц" по id (так как далее номера id будут перебираться в цикле)

338
Открытие файлов .pdf и .zip из ресурсов

Открытие файлов .pdf и .zip из ресурсов

Как открыть файлpdf из ресурсов?

348
Как сделать, чтобы после клика файл открывался в браузере?

Как сделать, чтобы после клика файл открывался в браузере?

С txt-файла при двойном клике по ссылке начинается скачивание исходного кода страницыКак сделать, чтобы он просто открывал ссылку в браузере?

236