local variables in document.ready() and other defined functions - javascript

In jQuery you can have multiple calls for the various page and other events, like so:
$(document).ready(function() {
And you can add multiple 'ready' function definitions along the way, you're not limited to only one. Of course this helps by keeping code defined close to where it's being used.
My question is, if in one of the document.ready function declarations I declare a local variable using var, will it be available in another document.ready function declaration that's also used by the page?
I'm not sure how jQuery works in circumstances like these; whether it weaves the various functions' scopes together somehow or if each of those functions runs in standalone fashion when the ready event is fired, each having no idea about the others' variables. (I'd guess the second.)

My question is, if in one of the document.ready function declarations I declare a local variable using var, will it be available in another document.ready function declaration that's also used by the page?
No, they're local variables to the function you're passing into document.ready.
I'm not sure how jQuery works in circumstances like these; whether it weaves the various functions' scopes together somehow or if each of those functions runs in standalone fashion when the ready event is fired, each having no idea about the others' variables. (I'd guess the second.)
And you'd be right. :-) In fact, jQuery can't comingle the execution contexts of the functions, those are managed by the JavaScript engine.
You can make them all share a parent execution context, though, by putting them all in a container function:
(function() {
// Shared by all functions within this block
var foo = 42;
// ...
$(document).ready(function() {
if (foo === 42) {
// ...
--foo;
}
});
// ...
$(document).ready(function() {
if (foo > 0) {
// ...
--foo;
}
});
})();
I don't think I'd advocate having multiple ready handlers (or even one, really) unless you're writing a library. But that's a different topic.

No it won't. Each $(document).ready will define it's own scope. If you need something visible to both, you can either make it a global, or define all your $(document).ready within another closure (using a self-invoking function for example).

Related

What is the difference between (function(){/*.....*/})(); and (function($){/*.....*/})(jQuery);

Is there difference between :
(function() {
/*..........*/
})();
and :
(function($) {
/*..........*/
})(jQuery);
Other people explained what the difference is, but not why you use the latter.
The $ variable is most often used by jQuery. If you have one script tag that loads jQuery and another that loads your code, it's perfectly fine. Now throw prototype.js into the mix. If you load prototype.js and then jQuery, $ will still be jQuery. Do it the other way around and now $ is prototype.js.
If you tried to use $ on such a page, you'd likely get errors or weird behavior.
There are many questions on StackOverflow about this problem. Plugins shouldn't assume much about the page they're loaded in, so they use this pattern defensively.
i am asking if there is difference between (function(){/…/})(); and (function($){/…/})(jQuery);
A little difference. In case of (function($){/*…*/})(jQuery); and absense of jQuery you'll get an error message immeditally after page loads. It's a simpler to detect jquery absense or incorrect order of scripts inclusion, when jquery-based code included before jQuery.
In case of (function(){/*…*/})(); you'll get an error message when code inside this construction actually call one of jQuery methods. It's harder to detect this error, but on the other side you can include your jquery-based scripts before jquery.
I prefer first case.
The second form, (function($){/*…*/})(jQuery); can be slightly safer when working in an environment where you don't (or can't) strictly enforce what code gets put on your site.
I used to work on a large site with a lot of third-party ads. These ads would often unsafely inject their own version of jQuery and occasionally they would override jQuery's global $ object. So, depending on how we wrote our code, we might be calling methods that no longer existed or had slightly different behaviour from what we expected. This could be impossible to debug, since some ads would never appear in our area or were excluded from our environment. This meant we had to be extremely protective of scope, inject our dependencies before any ad code had a chance to load, namespace anything that had to be global and pray no ad screwed with us.
Other answers are quite fragmented so I'd like to give a more detailed answer for the question.
The main question can be self-answered if you understand..
What does (function(argument){ /*...*/ })(value); mean?
It's a quick hand version of:
var tempFunction = function(argument){
/* ... */
}
tempFunction(value);
Without having to go through the hassle of conjuring up a new terrible name for a function that you will only call once and forget. Such functions are called anonymous functions since they aren't given a name.
So (function(){/*...*/})() is creating a function that accept no argument and execute it immediately, while (function($){/*...*/})(jQuery) is creating a function that accept one argument named $, and give it the value of jQuery.
Now that we know what the expression means, surely the first think on our mind is
"Why?". Isn't $ jQuery already?
Well, not exactly. We can never be sure. $ is an alias of jQuery, but other libraries can also use the same alias. As user #FakeRainBrigand already pointed out in his answer, prototype.js also use $ as its alias. In such cases, whichever library assigns its value to $ later wins out.
The practice of (function($){...})(jQuery) is very similar to an alias import in other programing languages. You are explicitly telling the system that your function:
Requires an object/library named jQuery, and
Within your function, $ means jQuery.
So even when someone include a new library later that override the alias $ at the global level, your plugin/framework still works as intended.
Because javascript is so... "flexible" in variable assignment, some people (including me) go as far as doing things like
var myApplication = (function($, undefined){ ... })(jQuery);
Apply the same understanding, it is easy to interpret the second argument part as: assign nothing to the variable undefined. So we can be sure that even if some idiot assigned a value to undefined later, our if(checkVariable === undefined){} won't break. (it's not a myth, people really do assign values to undefined)
When is it commonly used in javascript?
This anonymous function practice is most commonly found in the process of providing encapsulation for your plugin/library.
For example:
var jQuery = (function(){
var publicFunction = function(){ /* ... */}
var privateFunction = function(){ /* ... */}
return {
publicFunction : publicFunction
}
})();
With this, only jQuery.publicFunction() is exposed at the global scope, and privateFunction() remains private.
But of course, it is also used any time you simply want to create a function, call it immediately, and throw it away. (For example as a callback for an asynchronous function)
For the bonus question
why they used (function(){}() twice in the below code?
Well, most likely because they don't know what they're doing. I can't think of any reason to put nested function in like that. None at all.
(function(){/*...*/})(); does not set $ as reference to jQuery within IIFE and (function($){/*...*/})(jQuery); sets $ or other parameter name; e.g.; (function(Z){/*...* Z("body") where Z : jQuery*/})(jQuery); as reference to jQuery within IIFE
The they are both closures. The first is just an anonymous function that will fire any well formatted code that is inside immediately. The second is the jQuery closure. It is how the jQuery library initiates it wraps its code in the JQuery object and exposes it isn't the $ symbol.
(function(){}()) // this is a closure
(function($){}(jQuery)) // is a closure that wraps the executed code inside of the jQuery returned object and exposes it via the $.
With this (function(){/*…*/})();, you are not passing any argument to the inner function, while with this (function($){/*…*/})(jQuery); you are passing jQuery as argument to the inner function and expecting its value as $(which means, you will be able to use jQuery inside the inner function).
Ex:
(function($){
$(document).ready(function() {
console.log('all resources loaded');
})
})(jQuery);
They both are examples of Immediately Invoked Function Expression. In that sense, there is no difference between (function(){/*…*/})(); and (function($){/*…*/})(jQuery);. So no benefits are gained by wrapping (function($){/*…*/})(jQuery); inside (function(){/*…*/})();
A new execution context is created when a function is executed. So when (function(){/*…*/})(); is executed a context is created. Again when (function($){/*…*/})(jQuery); is executed, another context is created. Since the first context is not used (i.e. no variables are declared inside it), I don't see any advantages gained by the wrapping.
(function() { // <-- execution context which is not used
(function($) { // <-- another execution context
"use strict";
/*..........*/
})(jQuery);
})();

Why in javascript would an self-called anonymous function surround a jQuery onReady callback?

I am currently playing with playframework.
I started out with the tutorial which uses Coffeescript.
The CoffeeScript is converted to javascript, and this particular example, the javascript method needs to dynamically generate a list when the page is loaded.
The javascript generated uses a pattern that I've seen before, which I've read can be used for scoping variables or functions. That is, it envelopes everything inside an anonymous function.
However, within that anonymous function is the callback for window.isReady, in JQuery style.
(function() {
$(function() {
// the code within the callback goes here!
});
}).call(this);
Is this just due to the result of this having been generated by a set of programmed rules, or could there be a reason to have the callback inside the anonymous function? A reason to scope that JQuery onReady callback?
Of course, the functionality works without being enclosed by the self-called anonymous function. So, is there any benefit?
Since the function delimits a scope, you want to do this as a best practice to prevent polluting the global namespace.
In this simple example it might not be necessary since you don't save any variable, but you could have privates or other functions (and not have them global)
Like this:
(function() {
var a = 5;
var f = function() { ... }
$(function() {
// the code within the callback goes here!
f();
console.log(a);
});
}).call(this);
It's called an IIFE (Immediately Invoked Function Expression). Well...a flavor of it at least. You don't normally use .call for an IIFE, but it does the same thing. It's purpose in this case is mainly to prevent pollution of the global scope.
Learn about them here.

Troubles with (function(){})() [duplicate]

This question already has answers here:
What is the purpose of a self executing function in javascript?
(21 answers)
Closed 8 years ago.
So far I've learned the benefits of using this function (is it wrapping?)
So, it almost acts like namespaces.
Suppose we have:
( function() {
function foo(){
alert(true);
}
foo(); //alerts true
})();
( function() {
function foo(){ //the same title of the function as above
alert("another call of foo");
}
foo(); //alerts, ok.
})();
Also I've noticed it can access public vars, like this:
var __foo__ = 'bar';
( function() {
alert(__foo__); //alerts bar
})();
I have several questions regarding this approach
What I've tried:
Use Bing for tutorials (I' found them, but many of them don't answer my questions)
Play with passing objects into the body
Find the answer here
But, I'm still beating my head against the wall
So the questions are:
I've seen people pass objects as params, but when DOES it make sense?
For example, what does it mean?
( function(window) {
})(document);
I saw smth like this in Jquery UI Lib
( function($) {
//some code of widget goes here
})(Jquery);
This makes inner code visible outside the function, right? (not sure) Why, this is because
we can access the object (say we have "modal" widget), simply by calling it,
like:
$(function(){
$("#some_div").modal(); //here it's object the we got from the function
});
And the second question is: How does it work.
I've seen people pass objects as params, but when DOES it make sense? For example, what does it mean?
( function(window) {
})(document);
The language does not treat parameters to immediately called functions differently than parameters to other functions.
It makes sense to use a parameter whenever you want a local name in your function body for an input. In this case it's a bit confusing since window and document are likely to be confused.
( function($) {
//some code of widget goes here
})(Jquery);
This makes inner code visible outside the function, right? (not sure) Why, this is because we can access the object (say we have "modal" widget), simply by calling it,
No. It does not by itself make any code visible outside the widget. It's just a parameter definition which provides a new&local name for a global variable.
What makes inner code visible outside is attaching it to an external object as in
$.exportedProperty = localVariable;
which is a common convention in jQuery code.
There are mainly 2 purposes of passing in the window and document objects such as seen below
(function(window, document){
// code
}(window, document);
Javascript can access local variables faster than global variables. This pattern in effect makes the names window and document local variables rather than global, thus making your script slightly faster.
Making these names local variables has another benefit: minifiers can rename them. So if you minify the above script, the local version of window might get renamed to a and document might get renamed to b, thus making the minified script smaller. If you were to reference them as globals, these renamings are impossible because that would break your script.
For more info, checkout these awesome videos
http://paulirish.com/2010/10-things-i-learned-from-the-jquery-source/
http://paulirish.com/2011/11-more-things-i-learned-from-the-jquery-source/
on your first question, I dont think you seen window and document but something more like:
(function(doc) {
var fubar = doc.getElementById("fubar"); // === document.getElementById("fubar")
})(document);
you have a self-invoking function (or closure) with arguments like any function:
var b = function(str) { alert(str); }
b('hi there') //alert('hi there');
the same thing is it with the code above, but we are just calling the method at once we created it.
the other code you have:
( function($) {
//some code of widget goes here
})(Jquery);
is to reserve the $variable inside the metod to refer to the jQuery object, this is very handy if you have more frameworks or replaced the $ object with something else, everything inside that method with an $ will refer to the jQuery object and nothing else(if you don´t replace it inside your code).
the code:
$(function(){
$("#some_div").modal(); //here it's object the we got from the function
});
is calling jQuery and its a shortcut for $(document).ready
it will call the method:
function(){
$("#some_div").modal(); //here it's object the we got from the function
}
as soon as the DOM is ready
The pattern is called a closure. It makes sense to use when a module or function:
wants to avoid polluting globally-scoped variables
wants to avoid use globally-scoped variables and avoid other code polluting them
For an example of each, first take this pattern:
(function(window) {
// ...
})(window);
Everything inside the closure will be able to use window as if it were a local variable.
Next, take the same pattern using the JQuery symbol:
(function($) {
// ...
})($);
If you have some code that relies on a symbol/namespace like $, but another module reassigns that, it can screw up your code. Using this pattern avoids this by allowing you to inject the symbol into a closure.
Whenever you pass an argument to that wrapping function it's so that you won't mess up with any other libraries or global variables that may be present in your application.
For example as you may know jQuery uses $ as a symbol for calling itself, and you may also have another library, that will also use $ for calling itselt, under this condition you may have trouble referencing your libraries. so you would solve it like this:
(function($){
// here you're accessing jQuery's functions
$('#anything').css('color','red');
})(jQuery);
(function($){
// and in here you would be accessing the other library
$.('#anything').method();
})(otherLibrary);
This is specially useful when you're making jQuery or any other kind of library plugins.
What it does is allow you to use the $ variable inside your function in place of the jQuery variable, even if the $ variable is defined as something else outside your function.
As an example, if you're using both jQuery and Prototype, you can use jQuery.noConflict() to ensure that Prototype's $ is still accessible in the global namespace, but inside your own function you can use $ to refer to jQuery.

How are functions scoped/namespaced within a <script> tag?

I'm working with a new application at work that we're building out using Knockout.js and jQuery. I prefer to "use strict" in my scripts, but since some of the libraries we're using don't work with "use strict" then I have to use the functional form.
I don't like placing javascript inside <script> tags inline, so I generally place everything in a separate file so it can be minified and gzipped by a pre-processor.
Given these criteria, I'm wondering how functions are scoped by default when you create them within a script tag. Right now I'm just doing something like this:
$((function(win) {
"use strict";
win.myFunction = function () {
// do stuff
};
}(window)));
As you can see I'm placing functions on my window object so I can call them in my view. I've noticed that I can call them in my jQuery templates without qualifying them (i.e.: I can just call myFunction instead if window.myFunction), but I'm concerned that this will not work across browsers. Do all browsers allow you to call functions placed in the window object without the fully-qualified name? How could I place a function in the global scope from within my anonymous method as I've defined above?
Thanks for the insight!
The window object essentially is the global scope. Any variable that isn't scoped to a function is a property of the window object.
You can set a global variable by setting it as a property of the window object, as you just about do:
window.myFunction = function() {
// do stuff
}
However, it's probably not a good idea to litter your global namespace with names. That way chaos, unmaintainable code and bizarre bugs come in. All jQuery functions, for example, are properties or sub-properties of the jQuery (or $) object. This means that they can define jQuery.each and not have to worry about collisions with a global each method. You should consider doing the same with your own code: create a single global namespacing object to house all your "global" methods.

What javascript coding style is this?

I am working on maintaining a ASP.NET MVC application that has the following coding style. The view has:
<script type="text/javascript">
$(document).ready(function() {
SAVECUSTOMERS.init();
});
</script>
There is a js file included that goes along these lines:
var SAVECUSTOMERS = (function() {
init = function () {
$("#saveCust").bind("click", OnSave);
$("#cancel").bind("click", OnCancel);
},
OnSave= function() {
//Save Logic;
},
OnCancel = function() {
//Cancel logic;
}
return { init: init };
})();
Is this a best practices JS coding style? Is the intent to have non obtrusive JS?
What is the SAVECUSTOMERS? I understand that there are different ways of creating classes in javascript (per this link), but this style does not fall into any of those categories listed
Where can I find more information on this style of JS coding?
1) Using a $(document).ready (or similar function from another library) function is considered standard practice in JavaScript. First of all, it ensures your JavaScript executes on page that has finished evaluating/building it's DOM. And it also abstracts away some of the browser-implementation inconsistencies when identifying when the DOM is in fact ready. But I assume you are mainly referring to the 2nd code block.
What you see there is that SAVECUSTOMERS is assigned the result of a self-executing an anonymous function. This is done for a few reasons, the most common being the ability to control the scope and 'namespace' of the functions and data inside the anonymous function. This is because JavaScript has lexical scope, and not block level scope.
The practice of using these self-invoking functions in JavaScript is very common
However the code itself has several problems. The variables init, OnSave and OnCancel are declared as global variables (because the var keyword was omitted). This largely defeats the purpose of wrapping them in an self-invoking function. Furthermore, the contents of that function are using a mix of object assignment syntax and standard expression syntax, which will result in syntax errors.
Also, by returning only the init function, the onSave and onCancel functions have been effectively 'hidden' or made 'private' through the use of closures. This helps keep namespaces clean and encapsulated.
If I were writing this code (some personal perferences here, there are a few ways to accomplish something simliar), then it would look like this:
var SaveCustomers = (function($) {
var init = function () {
$("#saveCust").bind("click", onSave);
$("#cancel").bind("click", onCancel);
};
var onSave = function() {
//Save Logic;
};
var onCancel = function() {
//Cancel logic;
}
return { init: init };
})(jQuery);
Some notes on the above:
I declare variables using the var keyword. This keeps their scope local to this function (you could also technically use named functions declarations as well)
I pass jQuery as the parameter in the self-invoking function, and assign it to $ as the argument in the function call. This protects the $ variable inside the function so that we know it references jQuery, and hasn't been munged by a secondary library that also uses $.
2) SAVECUSTOMERS is a basic JavaScript object, which has a single owned property called 'init', whose value is a function, as defined by the init declaration inside the execution.
3) Not sure about how to answer this question - your best bet for understanding JavaScript best practices is to read through other JavaScript code that is known to be of quality, such as the jQuery source, or Prototype, or Underscore, etc.
this style is known as jquery ... have you checked the JQuery website, go through it ...
This is called self-invoking functions in javascript. One of the articles I am giving below. you can get more on google.
http://2007-2010.lovemikeg.com/2008/08/17/a-week-in-javascript-patterns-self-invocation/
If you are referring to the $ programming, then its related to JQuery which other answers have provided links too.
It's using the JQuery library.
JQuery includes a function called $(), which allows you to select elements from the DOM using a CSS-like syntax.
The $(document).ready bit is a standard JQuery method for making sure that the enclosed code only gets run after the page has finished loading. This is required to ensure that events get correctly attached to the relevant DOM objects.
The bit with functions being used as arguments for others functions is known as a 'closure' it's a very common way of writing Javascript, but in particular when using JQuery, which goes out of its way to make things easy to do and minimal code with this coding style.
See this page: http://blog.morrisjohns.com/javascript_closures_for_dummies for a beginners discussion of how closures work in Javascript and how to write them (note that this page doesn't look at JQuery at all; closures are a Javascript feature that is used heavily by JQuery, but you don't need JQuery to write closures)
This is a normal way to use jQuery for handling events.
What basicly happens is that you check that the document is loaded hence
$(document).ready(function() {
SAVECUSTOMERS.init();
});
And when it is you start to add your bindings to buttons or what ever they might be.
The intent of the code in SAVECUSOMTERS is to mimic private and public properties in objects. Since JS does not support these by default, this self invoking function executes and returns a certain number of properties. In this case it returns the 'init' method. Despite the fact that you see OnSave and OnClick, you'll find that you can't access them at all. They are "private" and only used internally within that function.
The $() function is part of a javascript library called jQuery http://jquery.com It's a pretty well rounded library and primarily is used for DOM manipulation.
The $(document).ready() function is a way for jQuery to continuously poll the page until it is loaded. When it is, the javascript within is executed.
The goal is to have public and private functions. OnSave and OnCancel are private functions that are only accessible within the scope of the self-executing anonymous (function() { ... } ()) which returns an object that gives access to the init function publicly.
SAVECUSTOMERS becomes the object returned by the above mentioned function, i.e. { init: init }, an object with one method init that has access to the functions within that closure.
You can read Douglas Crockford's Javascript: The Good Parts or Stoyan Stefanov's Javascript Patterns
Other notes:
The $() functions belong to the jQuery library
There are syntax errors because the functions should be separated by ; not , since they are within a function, not an object.

Categories

Resources