Код jQuery noConflict() не имеет смысла

Я не понимаю исходный код функции noConflict. Он находится в jQuery 3.3.1:

jQuery.noConflict = function( deep ) {
  if ( window.$ === jQuery ) {
    window.$ = _$;
  }
  if ( deep && window.jQuery === jQuery ) {
    window.jQuery = _jQuery;
  }
  return jQuery;
};

Почему они проверяют строгое равенство между window.jQuery и jQuery? (deep && window.jQuery === jQuery)

Как window.jQuery может содержать что-либо, кроме jQuery?

window.jQuery может быть равен jQuery, может быть неопределенным, я думаю, но не более того. Я думаю, что другие библиотеки не помещают jQuery в объект окна. И затем есть этот код из "Professional jQuery" (книга):

noConflict: function( deep ) {
     window.$ = _$;
     if ( deep ) {
        window.jQuery = _jQuery;
     }
     return jQuery;
}

который не использует window.jQuery === jQuery.

window.jQuery может быть уже определен другой версией jQuery или чем-то подобным, если вам нужно запустить более одной версии параллельно.

m90 09.04.2019 09:49

Но в этом случае мы можем передать значение true в noConfilct, например noConfilct(true), и этого будет достаточно, чтобы перезаписать window.jQuery предыдущим значением. Нет необходимости в window.jQuery === jQuery.

Darko 09.04.2019 09:59

Нет, если вы передадите true и window.jQuery (допустим, версия 2) будет нет равным jQuery (допустим, версия 3), вы не перезапишете его. Это связано с тем, что вы могли сначала загрузить jQuery2, а затем загрузить jQuery3 и вызвать для него .noConflict. Проблема становится очевидной, если у вас есть еще больше версий, загружающих jQuery 1, 2 и 3, тогда, если вы вызываете .noConflict для одной, вы не обязательно хотите, чтобы она восстанавливала предыдущее значение, поскольку это зависит от порядка, в котором они были загружены.

VLAZ 09.04.2019 10:05

Не будет ли разумнее, если вы спросите об этом прямо на github.com/jquery/jquery?

Carsten Løvbo Andersen 09.04.2019 10:08
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
4
76
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это в случае загрузки нескольких версий jQuery. Давайте сделаем образец здесь

function PseudoJQuery(version) {
  //keep track of version
  this.version = version;

  //keep previous $ and jQuery values
  var _$ = window.$;
  var _jQuery = window.jQuery;

  //assign the current version
  var jQuery = this;
  window.$ = jQuery;
  window.jQuery = jQuery;

  //re-use the jQuery.noConflict
  this.noConflict = function(deep) {
    if (window.$ === jQuery) {
      window.$ = _$;
    }
    //remove the check
    if (deep /*&& window.jQuery === jQuery */) {
      window.jQuery = _jQuery;
    }
    return jQuery;
  };
}

//load multiple versions of our jQuery
var j2 = new PseudoJQuery(2);
var j3 = new PseudoJQuery(3);

console.info("version after loading", window.jQuery.version);

j2.noConflict(true);

console.info("version after noConflict", window.jQuery.version); //error

Итак, это упрощенная версия того, что jQuery делает при инициализации и что пытается восстановить при вызове noConflict. Это терпит неудачу, потому что, когда мы вызываем j2.noConflict, переменная window.jQuery будет возвращена в исходное состояние — undefined, что уничтожит установку версии 3.

С установленной проверкой версия jQuery ток уничтожит себя только при вызове noConflict, но не при любой другой установке jQuery.

function PseudoJQuery(version) {
  //keep track of version
  this.version = version;

  //keep previous $ and jQuery values
  var _$ = window.$;
  var _jQuery = window.jQuery;

  //assign the current version
  var jQuery = this;
  window.$ = jQuery;
  window.jQuery = jQuery;

  //re-use the jQuery.noConflict
  this.noConflict = function(deep) {
    if (window.$ === jQuery) {
      window.$ = _$;
    }

    if (deep && window.jQuery === jQuery) {
      window.jQuery = _jQuery;
    }
    return jQuery;
  };
}

//load multiple versions of our jQuery
var j2 = new PseudoJQuery(2);
var j3 = new PseudoJQuery(3);

console.info("version after loading", window.jQuery.version);

j2.noConflict(true);

console.info("version after noConflict", window.jQuery.version);

Значит, _jQuery сохраняет свое значение даже после PseudoJQuery(2) вызова? Это закрывающий механизм? Если бы _jQuery было, скажем 3, после звонка PseudoJQuery(2), оно все равно было бы 3?

Darko 09.04.2019 11:37

Да, _jQuery виден только внутри закрытия, поэтому он не изменится после инициализации. И каждый экземпляр PseudoJQuery имеет свою собственную копию _jQuery. Для «версии 2» _jQuery содержит undefined, потому что ранее window.jQuery ничего не присваивалось. Для «версии 3» _jQuery содержит ссылку на «версию 2». Когда вы делаете версию 2, восстанавливаете значение, которое оно делает window.jQuery = undefined, хотя этого не должно быть.

VLAZ 09.04.2019 12:26

Извините за беспокойство, но если мы загрузим jQuery_v1, а затем jQuery_v2 и вызовем jQuery.noConflict(), это запустит jQuery_v2 noConflict?

Darko 09.04.2019 12:43

@Darko да, это правильно, но у вас все еще может быть ссылка на ранее загруженную версию jQuery, например, если вы динамически загружаете библиотеки. Таким образом, вы должны загрузить v2, получить ссылку на него, загрузить v3, а затем использовать ссылку на v2 для вызова .noConflict(). Это немного пограничный случай, но он все равно не должен сломать jQuery на странице. Одним из примеров того, как это может произойти, является ситуация, когда вы ставите в очередь некоторый асинхронный код и не уверены, когда именно каждый из них будет выполняться.

VLAZ 09.04.2019 13:20

В window.jQuery === jQuerywindow.jQuery будет содержать самое последнее значение, а не значение на момент выполнения PseudoJQuery(). А jQuery — это частная ценность, существующая только в PseudoJQuery(). И это значение сохраняется даже после того, как PseudoJQuery() перестанет выполняться. Просто поправьте меня, если я ошибаюсь, и у меня больше нет вопросов.

Darko 09.04.2019 20:42

@Darko да, window.jQuery - это значение Один для всего, потому что оно глобальное. Таким образом, он будет содержать только одну версию jQuery — без вызова .noConflict она будет последней загруженной. Переменная var jQuery существует для каждого пример PseudoJQuery. Когда вы вызываете .noConfluct(), этот метод имеет доступ только к своей собственной переменной jQuery, и, поскольку она не открыта, ничто извне не может ее изменить.

VLAZ 09.04.2019 20:56

Другие вопросы по теме