16

I found it here

;(function ($, window, document, undefined) {
//code
}(jQuery, this, this.document));

This is the first time I see something like this. What it is and how it is interpreted? I don't understand why does it have to pass this and this.document, and what's with the 'undefined'.

The reason I am asking is because I included it in my page and

  if($('ul.mtree').length)

Returns false, despite it returning true when I type it in the console.

George Irimiciuc
  • 4,573
  • 8
  • 44
  • 88

5 Answers5

16

The first semi-colon ; sets the following code apart from any other preceding code that may have forgot the semi-colon. This is important as the parens will try to run the previous statements as a function if the semi colon was not found.

For the rest of the code, we are just declaring an "in-line" function which will be immediately executed where the arguments $, window, document are then instantiated as jQuery, this, this.document (respectively) from the global scope. This is primarily so that you can use "$" within your new jQuery plugin without worrying if $ has been overwritten somewhere else. You can be sure that $ is the same as jQuery.

Read more about "Protecting the $ Alias and Adding Scope" here

Update from OP:

For the if statement returning false, be sure that your html is loaded at the time of calling your if statement. One quick way to do this, is to wrap it in a $(document).ready method like so:

$(document).ready(function () {
    if($('ul.mtree').length) {
         alert("got 'em!");
    }
});
KJ Price
  • 5,774
  • 3
  • 21
  • 34
  • 1
    Just to mention : it helps a lot with minifications of js code. – Royi Namir Apr 16 '15 at 15:22
  • Yes! Good point @RoyiNamir – KJ Price Apr 16 '15 at 15:24
  • 1
    Also : you forgot to mention that undefined could be overriden by a user code ( I dont think it's the case now days) but it is safest to send nothing to a variable so you can be certain that it has `undefined` value – Royi Namir Apr 16 '15 at 15:24
  • Nice about the `undefined`, I missed that. – KJ Price Apr 16 '15 at 15:26
  • The document ready didn't solve it, it was because that example was using an old version of velocity. And the curent version doesn't include that function(for everyone that might want to run that example). – George Irimiciuc Apr 18 '15 at 09:13
3

It's an immediately executed function. The ; at the start protects from potential syntax errors after minification.

The function itself provides for scoping of the arguments rather than referencing them at global scope. It also provides for privacy of local variables defined with the function. The somewhat confusing final parameter passed of undefined protects against malicious changes to what undefined represents at the global scope.

Lots of resources available if you google for javascript terms such as self executing functions, global scope, closures, module pattern.

Darren Lewis
  • 8,338
  • 3
  • 35
  • 55
2

It might be helpful to include a copy of the code you have which is not working.

But to answer the question about why if($('ul.mtree').length) can return true at console, but false in the page could depend on timing (e.g. the function executes before the DOM has loaded). By the time you load up the console to check the value, the DOM is loaded and it returns true.

Make sure to include your JS at the end of the page, or only call after document load.

MichaelM
  • 306
  • 2
  • 14
  • It might be helpful to include the "document load" syntax for the OP – KJ Price Apr 16 '15 at 15:31
  • Good call, I initially left it out since I didn't want to make any assumptions about OP's code.I would edit it in, but looks like you already edited your answer to include a sample so I'll leave mine alone to limit duplication. – MichaelM Apr 16 '15 at 15:39
1

Probably, that code is supposed to fix the case in which $, window or document have been shadowed with other values:

(function() {
var window = 123,
    document = 'abc',
    $ = Function.prototype;
})();

Then,

  • $ is a shorthand used by jQuery and other libraries. The code assumes jQuery hasn't been shadowed with something other, so it creates a variable named $ with the value of jQuery.
  • this is a keyword. When not explicitly set in non-strict mode, it becomes the global object. So your code creates a local variable window with that value. Note this is dangerous, because this could have been set to some value, or be undefined in strict mode.
  • Assuming this is the global object, this.document will be the document object.
  • undefined was a property of the global object which didn't have the ReadOnly attribute in ECMAScript 3, so it could be overwritten. Your code creates a local variable without assigning any value, so it becomes the real undefined. This is no longer needed since ECMAScript 5, because window.undefined has the [[Configurable]] and [[Writable]] attributes set to false.

Then,

(function() {
var window = 123,
    document = 'abc',
    $ = Function.prototype;
    (function($, window, document, undefined) {
        // `$`, `window`, `document` and `undefined` have been restored
    })(jQuery, this, this.document);
})();
Oriol
  • 274,082
  • 63
  • 437
  • 513
1

If i understand your question correctly,the function of notation ; ahead of the function statement,such as

(function(){
    console.log('no name');
})();

(function(){
    console.log('no name')
}());

-function(){
    console.log('no name');
}();

+function(){
    console.log('no name');
}();

~function(){
    console.log('no name');
}();

!function(){
    console.log('no name');
}();

you'll see the notation ,such as '()','-','+','~','!'

and the function of the notation is that parse the function statement into expression and execute the function immediately!

but i suggest you just use '()' to execute the function statement,because it is the formal way and regular way to use in routine.

qianjiahao
  • 399
  • 1
  • 3
  • 10