为什么要两次声明jQuery?

Lea*_*One 79 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>
Run Code Online (Sandbox Code Playgroud)

Dav*_*ret 122

jquery.min.jsCDN关闭或无法访问时,它将回退到存储在同一服务器上的文件.

它基本上是这样说的:

// 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>')
}
Run Code Online (Sandbox Code Playgroud)

在这里阅读更多,您可以在这里找到原始代码.

关于window.jQuery || document.write(...)这基本上是上述代码的简写.如果定义window.jQuery将是真实的,那么右边的陈述|| 将不会被执行; 但是,如果没有定义它将是假的,并且|| 执行右侧的声明.

  • @loneboat除此之外,HTML5提供了`async`属性,它使`<script>`标签的行为与您刚刚描述的方式相同 (6认同)
  • 很酷的概念,我以前从未见过这个.我们是否保证第一个<script>将在第二个<script>开始之前完成下载? (4认同)
  • @loneboat是的,它会在继续解析页面之前尝试下载并运行脚本([Source](https://developer.mozilla.org/en/docs/Web/HTML/Element/script)).这就是为什么如果按照特定顺序放置脚本标记,它将按顺序运行脚本,而不是先完成下载 (3认同)

Dav*_*oss 18

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

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

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

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


Buz*_*nas 7

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

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

window.jQuery || document.write(...)
// the code above means the same as the code below
if (window.jQuery === undefined) document.write(...)
Run Code Online (Sandbox Code Playgroud)

在Javascript中,除了布尔值(真/假)之外,还有真实和虚假的值.凡是是不同的0,false,undefined而且null是一个truthy值.

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

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