Вопрос

I saw an answer to some question earlier that used my "Weird" example, and I was wondering if there was any benefit to either method.

Some HTML:

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

What is the difference between:

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

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

And even, why do people use window.onload when they can put scripts at the bottom of the body? Or is it just a matter of personal preference?

Это было полезно?

Решение

  • Your first code snippet: is a Module Pattern Or Immediately Invoked Function Expression(IIFE)

    (function()//doing this
    {
        them.innerHTML = "Weird<br>";
    })();
    
  • This when encountered by the Javascript compiler will immediately invoke the function when it encounters (); and keeps the variables and functions within its scope.

    You must read Java-script Design Patterns to better understand its use and benefits.

  • Second code snippet: is just a JavaScript statement.

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

    This when encountered by the JavaScript compiler will immediately execute it.

Remember both snippets executions depends on where its placed.

  • So, to answer your other question. window.onload is an event fired when the HTML DOM is fully loaded and browser can read all its elements.

Другие советы

  1. There is no difference between your two examples. Your first example creates an anonymous function that immediately executes (called an Immediately Invoked Function Expression). Your second example just executes the same code.

  2. You have to wait until a browser reads all the HTML elements before you can change them with JavaScript. The onload event fires when the page has fully loaded and at that time the browser knows about all the HTML elements. However, a browser won't fire the onload event until after the page has fully loaded, which means the browser will wait until after a large image has fully loaded -- even though the browser has already parsed the rest of the HTML -- making your JavaScript needlessly wait until the image finishes loading. Because the browser knows about all the HTML before the image finishes loading there is no reason to prevent JavaScript from executing earlier.

Once people discovered that onload was waiting too long before allowing the JavaScript to execute, people started putting their JavaScript right before the closing <body> tag (without using onload), so that the JavaScript would execute as soon as all the HTML had been parsed (except for the closing <body> tag), and that way their JavaScript could start executing sooner than when using window.onload.

Now JavaScript libraries like jQuery have an event that fires when the browser knows about all the HTML -- even though the page hasn't fully loaded (e.g. due to images that haven't fully loaded).

In your simple example, there is no difference between the result of the two cases. Both accomplish the same thing.

The reason for using this structure:

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

Is to create a function scope that can be used to hold private or temporary variables or to create a closure without exposing the variables inside to the outside world.

As for your second question, window.onload fires at a different time than scripts placed at the end of the body because window.onload fires when all synchronous resources needed by the page have finished loading (like scripts and images). It can be used, either to get notified when all these resources are done loading or it can be used by code that cannot be easily located at the end of the body as a safe time when the page is ready though it is usually not necessary to wait that long just for the DOM to be safe.

In the above case there is not advantage in using the first method.

But the first method is preferable in scenarios where you need to create some variables/method but does not want to pollute the global name space

After some thought, there is a benefit over writing the extra (function(){})(); as shown (imagine the code is huge):

(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
})();

This will be quite handy for debugging many lines of code, the debugger would recognise the error and "point" straight to it.

Whereas with this example:

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

Your "error" (which the debugger is perfectly happy with) would be much harder to track down.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top