What does !function ($) { $(function(){ }) }(window.jQuery) do?
JqueryJquery TooltipJquery Problem Overview
I'm using twitter bootstrap to create a site and was trying to initialize tooltips. Apart from adding something like:
$("[rel=tooltip]").tooltip()in application.js , unless I retain, the following piece of code used in bootstrap docs, my tooltips don't initialize.
!function ($) {What does the above code do?$(function(){
})
}(window.jQuery)
Jquery Solutions
Solution 1 - Jquery
Lets explain by Breaking up the code
function () {
}()
Or often written as
(function () {
})()
Is a self-invoking anonymous
function, also known as Immediately-Invoked Function Expressions (IIFEs). Which executes the anonymous function inline immediately.
Read more about this at https://stackoverflow.com/q/1634268/1048572.
Anonymous functions are a powerful feature and have benefits like scoping ("variable name spacing"), see https://stackoverflow.com/q/592396/1048572.
Now they are using
function ($) {
}(window.jQuery)
Let's skip the !
for now.
So they are passing, window.jQuery
into that function as argument and accepting as $
.
What this does is making $
an alias to window.jQuery
(original jQuery Object) and hence ensuring that the $
will always refer to the jQuery object
inside that closure
, no matter if other library has taken that($
) outside.
So code you write inside that closure using $
will always work.
Another benefit is that $
comes as an argument in the anonymous function, which brings it closer in the scope chain
and hence it takes less time for the JS interpreter to find the $
object inside the closure than it would otherwise took if we used the global $
.
$(function(){
})
It's jQuery's document ready block as you might already know, which ensures that code inside this function will run when dom is ready
, and hence all event binding's
will work properly.
Read more at http://api.jquery.com/ready/
And what that !
does has been well explained here or at https://stackoverflow.com/q/3755606/1048572
In Short:
To demonstrate the benefits of !
, Lets consider a case,
(function() {
alert('first');
}())
(function() {
alert('second');
}())
If you paste the above code in console
, you will get two alerts, but then you will get this error
TypeError: undefined is not a function
Why this happens? Let's simulate how JS engines executes the above code block. It executes this anonymous function function() {alert('first');}()
shows the alert and as it returns nothing undefined
is returned inside the ()
. Same happens for the second function too. So after the execution of this block, it ends up having something like
(undefined)(undefined)
and as it's syntax is like a self-invoking anonymous
function, it tries to call that function, but the first, (undefined)
is not a function. So you get undefined is not a function
error. !
fixes this kind or errors. What happens with !
. I am quoting the lines from the above answer link.
> When you use !, the function becomes the single operand of the unary > (logical) NOT operator. > > This forces the function to be evaluated as an expression, which > allows it to be invoked immediately inline.
and this solves the above problem, we can rewrite the above block using !
like
!(function() {
alert('first');
}())
!(function() {
alert('second');
}())
For your case you can simply put your tooltip code inside a document ready block like this
$(function(){
$("[rel=tooltip]").tooltip();
});
and it will work fine.
And if you just use $("[rel=tooltip]").tooltip()
without any doc ready block
, then there is a chance when this code will run, there isn't any element with rel=tooltip
in DOM yet. So $("[rel=tooltip]")
will return an empty set and tooltip
won't work.
An example markup when it won't work without doc ready block
,
.
.
.
<script type="text/javascript">
$("[rel=tooltip]").tooltip();
</script>
.
.
.
.
<a href="#" rel="tooltip">Something</a>
<a href="#" rel="tooltip">Something</a>
<a href="#" rel="tooltip">Something</a>
As browsers, interprets the markup sequentially, it will execute the js code as soon as it face it as. And when it executes the JS block here, it hasn't yet parsed the a rel="tooltip"
tags yet, as it appears after the JS block, So they are not in DOM at that moment.
So for the above case $("[rel=tooltip]")
is empty and hence tooltip won't work. So it's always safe to put all your JS code inside document ready
block like
$(function){
// put all your JS code here
});
Hope all this makes sense to you now.