JavaScript模块模式(function(){})(); vs块语句

时间:2013-05-31 03:32:42

标签: javascript onload module-pattern

我之前看到了一些使用我的"Weird"示例的问题的答案,我想知道这两种方法是否有任何好处。

一些HTML:

<span id="them">Hey</span>
<span id="me">Hey</span>

有什么区别:

(function()//doing this
{
    them.innerHTML = "Weird<br>";
})();

me.innerHTML = "Not so weird<br>";//and doing this

甚至,为什么人们在将脚本放在身体底部时会使用window.onload?或者只是个人偏好的问题?

5 个答案:

答案 0 :(得分:2)

  1. 两个例子之间没有区别。您的第一个示例创建一个立即执行的匿名函数(称为立即调用的函数表达式)。您的第二个示例只执行相同的代码。

  2. 您必须等到浏览器读取所有HTML元素,然后才能使用JavaScript更改它们。页面完全加载时会触发onload事件,此时浏览器会知道所有HTML元素。但是,浏览器不会触发onload事件,直到页面完全加载为止,这意味着浏览器将等到大图像完全加载后 - 即使浏览器已经解析了其余部分的HTML - 使你的JavaScript不必要地等到图像完成加载。因为浏览器在图像加载之前知道所有HTML,所以没有理由阻止JavaScript先前执行。

  3. 一旦人们发现onload在允许执行JavaScript之前等待的时间太长,人们就会在结束<body>标记之前开始使用他们的JavaScript(不使用onload),这样只要解析了所有HTML,JavaScript就会执行(关闭<body>标记除外),这样他们的JavaScript就可以比使用window.onload时更快地开始执行。

    现在像jQuery这样的JavaScript库会在浏览器知道所有HTML时触发事件 - 即使页面没有完全加载(例如由于图像没有完全加载)。 / p>

答案 1 :(得分:2)

  • 您的第一个代码段:Module PatternImmediately Invoked Function Expression(IIFE)

    (function()//doing this
    {
        them.innerHTML = "Weird<br>";
    })();
    
  • 当遇到();时,Javascript编译器遇到此函数会立即调用该函数,并将变量和函数保留在其范围内。

    您必须阅读Java-script Design Patterns以更好地了解其用途和好处。

  • 第二个代码段:只是一个JavaScript语句。

    me.innerHTML = "Not so weird<br>";//and doing this
    

    当JavaScript编译器遇到这种情况时会立即执行它。

请记住,两个片段的执行取决于它的放置位置。

  • 所以,回答你的另一个问题。 window.onload是HTML DOM完全加载并且浏览器可以读取其所有元素时触发的事件。

答案 2 :(得分:1)

在您的简单示例中,两种情况的结果没有区别。两者都完成了同样的事情。

使用此结构的原因:

(function()//doing this
{
    them.innerHTML = "Weird<br>";
})();

创建一个函数作用域,可用于保存私有或临时变量或创建闭包,而不会将变量暴露给外部世界。

关于你的第二个问题,window.onload在与身体末端的脚本不同的时间触发,因为window.onload在页面所需的所有同步资源完成加载时触发(如脚本和图片)。可以使用它,或者在所有这些资源加载完成时得到通知,或者它可以被代码使用,这些代码在页面准备就绪时不能轻易地位于正文末尾,尽管通常没有必要等待那么长时间只是让DOM安全。

答案 3 :(得分:0)

在上述情况下,使用第一种方法没有优势。

但是在需要创建一些变量/方法但不想污染全局名称空间的情况下,第一种方法更可取

答案 4 :(得分:0)

经过一番思考,如图所示,编写额外的(function(){})();有一个好处(想象代码很大):

(function()
{
    var text = "Span 'them' text!";
    them.innerHTML = text;
    //Many lines of code
})();

(function()
{
    me.innerHTML = text;//will throw 'text is undefined'
    //Many lines of code
})();

这对于调试多行代码非常方便,调试器会识别错误并直接“指向”它。

而这个例子:

var text = "Span 'them' text!";
them.innerHTML = text;
//Many lines of code
//...
me.innerHTML = text;

您的“错误”(调试人员非常满意)将更难以追踪。