Зачем дважды объявлять jQuery?

Какова цель следующего кода?

Обратите внимание, что перед вторым кодом script ниже jquery.min.js уже включен в googleapis.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="/assets/js/vendor/jquery.min.js"><\/script>')</script>

Ответ 1

Откажитесь от файла jquery.min.js, хранящегося на том же сервере, когда CDN недоступен или не может быть достигнут.

По существу говоря:

// 1. Try to download and run https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js

// 2. Was jQuery successfully loaded from the CDN? If so, it will be defined:
if (window.jQuery) {
    // Yes, it defined. Good. Nothing more needed.
}
else {
    // No, it not defined. Use my copy:
    document.write('<script src="/assets/js/vendor/jquery.min.js"><\/script>')
}

Подробнее здесь, и вы можете найти исходный код здесь.

Относительно window.jQuery || document.write(...), который по существу является сокращенным для кода выше. Когда определено window.jQuery будет truthy, и поэтому инструкция в правой части || не будет выполнена; однако, если он не определен, он будет falsy, и инструкция в правой части || будет выполнена.

Ответ 2

Сначала пытается использовать версию, размещенную на Google CDN. Вероятность того, что у человека, просматривающего сайт, уже есть точный script кешированный из посещения какого-либо другого сайта, чтобы они могли сначала попробовать это.

Если версия CDN загружена, устанавливается window.jQuery, или закорочен, и код перемещается.

Если версия CDN не может быть загружена по какой-либо причине, она добавляет еще один тег script на страницу, указывающую на локальную версию script.

Изменить: поскольку MTCoster указывает на комментарий выше, этот трюк зависит от способа загрузки JavaScript. Браузер приостанавливает выполнение, пока тег не загрузится или не истечет время ожидания. Если jQuery был загружен асинхронно с использованием атрибута async, этот трюк не сработает.

Ответ 3

Первый script попытается загрузить jQuery с внешнего веб-сайта (в данном случае, CDN).

Второй попытается найти объект jQuery в window, и только если он его не найдет, он загрузит библиотеку из внутренней ссылки. Это только резерв в случае сбоя CDN.

window.jQuery || document.write(...)
// the code above means the same as the code below
if (window.jQuery === undefined) document.write(...)

В Javascript, кроме booleans (true/false), есть значения правды и фальшивости. Все, что отличается от 0, false, undefined и null, является правдивым значением.

В этом случае, если свойство jQuery существует в окне, это будет объект, и это будет правное значение, поэтому второй оператор не будет выполняться (поскольку первый из них уже является истинным) и в операторе OR, если какое-либо из утверждений истинно, оно пропускает другие (слева направо).

Хотя, если свойство jQuery не существует, это потому, что первый script не загрузился правильно, а свойство будет undefined, значение фальшиво. Таким образом, будет выполняться второй оператор, и локальный jQuery будет загружен как резерв.

Ответ 4

Это резервный механизм, если jquery из CDN не был достигнут по какой-либо причине, например, заблокирован брандмауэром, CDN и т.д.

Я добавлю еще один практический сценарий, с которым я столкнулся в прошлом году. Один из моих клиентов решил разместить и использовать веб-приложение, созданное мной в локальной сети, без доступа в Интернет. В локальном IIS приложение было развернуто правильно, но не выполнено из-за недоступности CDN, если бы я использовал упомянутый код, веб-приложение работало бы в первый раз без каких-либо изменений.

Я надеюсь, что это будет иметь смысл сейчас:) Для меня это был извлеченный урок.