为什么要声明两次 jQuery

Why declare jQuery twice?

本文关键字:两次 jQuery 声明 为什么      更新时间:2023-09-26

以下代码的目的是什么?

请注意,在下面的第二个脚本代码之前,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>
这是

在 CDN 关闭或无法访问时回退到存储在同一服务器上的jquery.min.js文件。

它本质上是在说:

// 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's defined. Good. Nothing more needed.
}
else {
    // No, it's not defined. Use my copy:
    document.write('<script src="/assets/js/vendor/jquery.min.js"><'/script>')
}

在此处阅读更多内容,您可以在此处找到原始代码。

关于window.jQuery || document.write(...),这基本上是上述代码的简写。当定义时window.jQuery将是真实的,因此||右侧的语句不会被执行;但是,如果未定义,它将是伪造的,并且||右侧的语句将被执行。

它首先尝试使用Google的CDN上托管的版本。查看该网站的人有可能已经缓存了访问其他网站的确切脚本,因此他们不妨先尝试一下。

如果加载了CDN版本,则设置了window.jQuery,OR短路,代码继续。

如果由于某种原因无法加载 CDN 版本,则会向指向脚本的本地托管版本的页面添加另一个脚本标记。

编辑:正如MTCoster在上面的评论中指出的那样,这个技巧依赖于JavaScript通常加载的方式。浏览器会暂停执行,直到代码加载或超时。如果使用 async 属性异步加载 jQuery,则此技巧将不起作用。

第一个脚本将尝试从外部网站(在本例中为 Google CDN)加载 jQuery。

第二个将尝试在window中找到jQuery对象,并且只有在找不到它时,它才会从内部链接加载库。这只是 CDN 失败时的后备。

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

在Javascript中,除了布尔值(真/假)之外,还有真值和假值。任何与0falseundefinednull不同的都是真实值。

在这种情况下,如果 window 上存在 jQuery 属性,它将是一个对象,它将是一个真值,因此,第二个语句将不会运行(因为第一个语句已经为 true - 并且在 OR 运算符中,如果任何语句为 true,它将跳过其他语句(从左到右)。

虽然,如果 jQuery 属性不存在,那是因为第一个脚本未正确加载,并且该属性将被undefined,这是一个错误的值。因此,第二个语句将运行,本地 jQuery 将作为回退加载。

如果由于某种原因(例如被防火墙阻止,CDN关闭等原因无法访问来自CDN的jquery),则这是一种回退机制

我将补充一个我去年面临的实际情况。我的一位客户决定在没有互联网可用性的情况下托管和使用我在局域网中创建的 Web 应用程序。使用本地 IIS,应用程序已正确部署,但由于 CDN 不可用而失败,如果我使用了有问题的代码,Web 应用程序将在第一次运行时无需任何更改。

我希望现在有意义:)对我来说,这是一个教训。