I'm trying to learn javascript better. There is a lot I don't know, for example, I have this simple code, should it be in a function that calls it's self? Or should I leave it like this? And why?
<script type="text/javascript">
$('.some_ul_class').each(function(i, obj) {
var childrenCount = $(this).find('li').length;
$(this).addClass('li-count-' + childrenCount);
});
</script>
Functions have two purposes in JavaScript:
Controlling scope.
Allowing code to be reusable.
You aren't creating any variables in the global scope, so there is no scope change by using a function.
That leaves allowing code to be reusable. Do you want to call that piece of code multiple times? If so, use a function.
To me this use of jQuery looks ok.
However, I wouldn't choose to use jQuery to add classes in this way.
If the items in your jQuery selector are part of a list, the classes could/should be added by the server in the loop that created them in HTML.
To me the jQuery snippet introduces some magic that can be hard to debug later on.
Related
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);
})();
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.
I'm going to be writing a callable function which will make use of jQuery. But I can't find any reference to ordinary function declaration with jQuery; it's all about element manipulation functions. Can I essentially just declare an ordinary javascript function and then use jQuery in it, or do I need to be doing something special? Is this okay?
function useJQ(xml)
{
var groups = {};
$('resultGroups', $(xml)).each(function() {
var count = $('results', this).length;
var name = $('name',this).text();
groups[name] = count;
}
You need not extend jQuery to do such tasks. You can use plain functions to do what you need to do. just ensure that you don't pollute the global namespace by setting your own namespace.
However, if just want to use the jQuery namespace instead of your own, here's a quick way to add them:
$.fn.functionName = function(){
//do what your function does
//"this" in here is the jQuery object you preceded the function
//to allow chaining, you must return a jQuery object
};
the effect is like:
$(selector).functionName()
jQuery is just a collection of helper functions. It doesn't affect how you define your functions. So your present code will work fine.
jQuery is not about structuring your javascript code, for that you should use Javascript enclosures, objects and prototype. There a many proposed ways of structuring Javascript code.
You could also take a look at defining jQuery plugins authoring to help you keep you code more organized.
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.
window.setInterval("moveUp(fire,2)","100");
in the code above fire is a object represting a div. I want to pass this object to moveUp method and call this method continuosly.
My problem is window.setInterval does not accepts fire object like this and gives error as fire is not defined. Although i am using fire object at other places as well. Besides this i also want to know if i can do the same using jQuery.
If you pass a string to setInterval then it will be evaled in the global scope. Don't do that. Pass a function instead, and keep the existing scope.
var fire = something;
var func = function () {
moveUp(fire, 2);
};
setInterval(func,100);
Besides this i also want to know if i can do the same using jQuery.
jQuery is just a JavaScript library. It isn't a different language. It doesn't have alternatives for basic JavaScript.
Best Way would be to use an anonymous function:
setInterval(function(){
moveUp(fire,2);
},100);
It actually does look a little bit like jQuery now... kidding aside, there is no setInterval Implementation for jQuery since its syntax and the cross browser capabilities are just fine the way they are - are they not?