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



我之前看到了使用"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?还是仅仅是个人喜好的问题?

  • 您的第一个代码片段:是模块模式或立即调用函数表达式(IIFE(

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

    您必须阅读Java脚本设计模式,才能更好地了解它的用途和好处。

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

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

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

记住这两个代码段的执行取决于它的位置。

  • 所以,回答你的另一个问题。window.onload是在HTML DOM完全加载并且浏览器可以读取其所有元素时触发的事件
  1. 你的两个例子没有区别。您的第一个示例创建了一个立即执行的匿名函数(称为"立即调用函数表达式"(。您的第二个示例只是执行相同的代码。

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

一旦人们发现onload在允许JavaScript执行之前等待的时间太长,人们就开始将他们的JavaScript放在关闭的<body>标签之前(不使用onload(,这样,一旦所有HTML都解析完毕,JavaScript就会立即执行(除了关闭的<body>标签(,这样,他们的JavaScript可以比使用CCD_ 11时更快地开始执行。

现在,像jQuery这样的JavaScript库在浏览器知道所有HTML时会触发一个事件——即使页面还没有完全加载(例如,由于图像没有完全加载(。

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

使用这种结构的原因:

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

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

至于您的第二个问题,window.onload在与放置在正文末尾的脚本不同的时间激发,因为window.onload在页面所需的所有同步资源(如脚本和图像(加载完成时激发。它既可以用于在所有这些资源加载完成时得到通知,也可以用于无法轻松定位在正文末尾的代码,作为页面准备就绪时的安全时间,尽管通常不需要等待那么长时间来确保DOM的安全。

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

但是,在需要创建一些变量/方法但不想污染全局名称空间

的情况下,第一种方法更可取

经过一番思考,与编写如图所示的额外(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;

您的"错误"(调试器对此非常满意(将更难追踪。

最新更新