JavaScript片段代码说明

时间:2012-04-09 00:54:48

标签: javascript jquery

查看这段JavaScript代码:

(function (w, d) {
    var loader = function () {
        var s = d.createElement("script"), tag = d.getElementsByTagName("script")[0];
        s.src = "https://example.org/script.js";
        tag.parentNode.insertBefore(s,tag);
    };
    w.addEventListener ? w.addEventListener("load", loader, false) :
                         w.attachEvent("onload", loader);
}) (window, document);

为什么此代码的作者使用此方法在文档中包含脚本? 这条线的用处是什么:

w.addEventListener ? w.addEventListener("load", loader, false) :
                     w.attachEvent("onload", loader);

最后一点:我是JavaScript初学者,最后是(window, document)是什么?

10 个答案:

答案 0 :(得分:3)

第一个问题,代码检查是否定义了window.addEventListener。如果是,则使用它,否则使用window.attachEvent。这是为了兼容浏览器。

第二个问题,这段代码是一个匿名函数,它带有2个参数,w和d。立即调用此函数,传递参数windowdocument

答案 1 :(得分:2)

首先,w.addEventListener ?确保浏览器是否支持window的addEventListener方法

其次,(window, document)只是他在function(w,d) {}之前写的匿名函数的参数调用

答案 2 :(得分:2)

以下addEventListener行是注册函数,以便在页面加载完成时调用它。 Internet Explorer和Firefox(等)使用不同的功能来执行此操作。

w.addEventListener ? w.addEventListener("load", loader, false) :
                 w.attachEvent("onload", loader);

在javascript中,函数本身就是一个对象。因此,它的“值”可以分配给变量或立即消耗。要立即使用它必须用括号括起来(否则它不会做你想要的),然后把它称为常规函数。

(function (w, d) { ... }) (window, document);

如果我们将它分成两行,那就更明显了。

var a = function(w, d){ ... };
a(window, document);

这样做是为了不用临时值或函数污染全局范围。更不用说不要诋毁任何其他变量。这可以分为两部分:

  1. 通过将代码封装在闭包中,内部显式声明的任何内容都在闭包的范围内,而不是全局范围。 var loader处于封闭范围内。
  2. 通过立即使用闭包,它不会存储在全局范围的变量中。由于它是匿名声明的,因此它不会作为全局范围内的命名函数存在。

答案 3 :(得分:1)

在附加脚本标记之前,作者似乎正在等待页面完全加载。 addEventListener(DOM级别2)和attachEvent(Microsoft的东西)是更灵活的附加事件的方式。代码类似于w.onload = loader

最后一点是将参数传递给匿名函数,它们被命名为wd。通过将()放在最后,立即调用匿名函数。

答案 4 :(得分:1)

所以函数包含在一个闭包中。这反过来意味着w = windowd = document

当调用该方法时,它会创建一个名为loader的函数,它是两个可能的事件监听器触发器之一的回调(意思是,当load或{{{在窗口上调用1}}事件。

onload语法是速记x ? y : z

如果我们扩展它,它看起来像这样:

if then else

该语句用于为IE和其他浏览器提供方法。

答案 5 :(得分:1)

这实际上与:

相同
function RegisterEventListener(w, d) {
    var loader = function () {
        var s = d.createElement("script"), tag = d.getElementsByTagName("script")[0];
        s.src = "https://example.org/script.js";
        tag.parentNode.insertBefore(s,tag);
    };
    if (w.addEventListener) {
       w.addEventListener("load", loader, false);
    } else {
       w.attachEvent("onload", loader);
    }
}

RegisterEventListener(window, document);

唯一真正的区别是:

  1. 如果你定义一个匿名函数(使用function () {};)而没有将它分配给任何东西,它只能用于有限的使用(因为没有办法引用它)。同时,匿名函数也允许立即执行(如问题function(a, b) {}(a, b);中的代码中的那个。
  2. condition ? true : false(第三级运算符)只是编写简单if语句的简写,因此需要较少的输入才能写出来,但有些人也认为它的可读性较低。

答案 6 :(得分:1)

我可能错了,但这是Google使用他们的分析脚本实现的。

这称为闭包,一个自动执行的函数,并将变量包含在内部,因此它们不会弄乱你的代码。

此代码实质上创建了一个脚本标记,并在它在文档中找到的第一个脚本标记之前将其附加到DOM。

第一个问题的答案是关于浏览器兼容性。某些浏览器使用addEventListener和其他attachEvent将事件附加到页面中的元素(在本例中为窗口),它将在窗口的load事件上显示(所有内容加载后,文件准备就绪)。请查看此更详细的答案:window.onload vs $(document).ready()

第二个答案很简单。这是闭包中使用的参数(自动调用函数),可以这种方式读取:

function anonymous(w, d) {
    ...
}
anonymous(window, document);

答案 7 :(得分:1)

此代码的作者使用包含在闭包中的匿名函数来触发函数,该函数注册一个load事件。在窗口的onload事件触发之前,实际上不会加载页面上的脚本。

作者可能会延迟脚本加载的原因可能是在实际加载其他脚本之前为网页提供更多时间进行渲染。这是一种很好的技术,可以快速加载页面内容,同时延迟加载不需要的资源。

作者使用的技术是一个包含在闭包中的匿名函数。想象一下:

myFunction (window, document);

现在,我将用匿名函数替换函数调用:

function(w, d) {
    // do stuff
    alert("w = " + w); 
    alert("d = " + d);
}

现在我将使该功能立即运行,而不是实际给它起一个名字。我还要将两个参数传递给该匿名函数:

( function(w, d) {
      // do stuff
      alert("w = " + w);
      alert("d = " + d);
})  ("1234", "5678");

此示例中的输出为:

w = 1234
d = 5678

如果你看括号并匹配它们,第一个外括号匹配字符2最后一行的右括号,即函数名,下面的一组括号将传递给函数的两个值包装起来参数。

这可能是一个难以掌握的概念;在你看到它完成几次之后,它开始变得更有意义。

答案 8 :(得分:1)

  1. 以这种方式添加脚本允许作者在不直接编辑HTML文件的情况下将该脚本包含在文档中。也可用于仅在需要时动态加载脚本。 (即如果你有一堆代码来编辑页面上的内容,你不想在用户实际点击编辑按钮之前下载它,这样你就不会在不需要时浪费带宽。)

  2. addEventListener和attachEvent是在页面加载完成后触发函数的方法。在这种情况下,有一个名为loader的函数 两者的原因是一些浏览器支持一个,一些支持另一个。我一直在使用jQuery,我不记得哪个是。

  3. (窗口,文档)是一种将这些变量封装在范围内和/或通过简写w和d引用它们的方法。作者正在创建一个期望这些参数的函数,然后将窗口和文档作为参数传递。

  4. 该闭包还可以帮助作者避免让他的脚本与页面上的其他脚本冲突。想想在那里声明的每个变量,就像它是其他语言中的私有变量一样。

答案 9 :(得分:1)

第一个代码块末尾的window, document是代码块其余部分中定义的匿名函数的参数。由于Javascript几乎是一种函数式语言,程序员可以定义这些匿名函数,甚至可以使用它们而不给它们命名。

您使用问号粘贴的代码块是中缀表示法的示例,这是一种符合此模式的语言结构:condition ? ifTrueExpression : ifFalseExpression。如果condition为真,则整个表达式将等于ifTrueExpression。否则,整个表达式将等于ifFalseExpression

使用您粘贴的中缀表示法在检测正在使用哪种类型的互联网浏览器时很常见。虽然,我不确定这个代码块试图检测哪个浏览器,但它的目的是以浏览器特定的方式实现事件处理程序。