2

我之前看到了一个使用我的"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甚至,当人们可以将脚本放在身体底部时,为什么还要使用呢?还是只是个人喜好问题?

4

5 回答 5

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

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

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

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

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

    JavaScript 编译器遇到 this 时会立即执行它。

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

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

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

一旦人们发现onload在允许 JavaScript 执行之前等待太久,人们就开始将 JavaScript 放在结束<body>标记之前(不使用onload),这样 JavaScript 就会在所有 HTML 被解析后立即执行(除了结束<body>标记),这样他们的 JavaScript 就可以比使用window.onload.

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

于 2013-05-31T03:47:51.890 回答
1

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

使用这种结构的原因:

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

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

至于您的第二个问题,window.onload在与放置在正文末尾的脚本不同的时间触发,因为window.onload当页面所需的所有同步资源完成加载(如脚本和图像)时触发。它可以用于在所有这些资源完成加载时得到通知,或者它可以被不易位于正文末尾的代码用作页面准备好的安全时间,尽管通常不需要等待那么久只是为了 DOM 是安全的。

于 2013-05-31T03:46:30.890 回答
0

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

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

于 2013-05-31T03:47:16.047 回答
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;

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

于 2013-05-31T04:03:56.360 回答