为什么要两次声明jQuery?

时间:2016-04-27 02:05:32

标签: javascript jquery

以下代码的目的是什么?

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

4 个答案:

答案 0 :(得分:122)

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>')
}

Read more here您可以找到原始代码here

关于window.jQuery || document.write(...),它基本上是上述代码的简写。如果定义window.jQuery将为truthy,那么|| 右侧的语句将不会执行;但是,如果它未定义,则为falsy,并且|| 右侧的语句将执行。

答案 1 :(得分:18)

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

如果CDN版本加载,则设置window.jQuery,将被短路,代码将继续运行。

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

编辑:正如MTCoster在a comment above中指出的那样,这个技巧依赖于JavaScript正常加载的方式。浏览器暂停执行,直到标记加载或超时。如果使用 async 属性异步加载jQuery,那么这个技巧将不起作用。

答案 2 :(得分:7)

第一个脚本将尝试从外部网站(在本例中为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不同的任何内容都是真实的价值。

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

虽然,如果jQuery属性不存在,那是因为第一个脚本没有正确加载,属性将是undefined,这是一个假值。因此,第二个语句将运行,本地jQuery将作为后备加载。

答案 3 :(得分:3)

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

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

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