jQuery variable shadowing - javascript

There is strange pattern in jQuery:
var jQuery = (function() {
// Define a local copy of jQuery
var jQuery = function( selector, context ) {
...
return jQuery;
})();
What is the practical reason for this? Why not just expose the inner jQuery function? Is it only for name clashes in the inner jQuery and outer jQuery since both are in closures.

jQuery.noConflict(true) removes the global name for jQuery. However, it would be impossible to program the rest of the jQuery library without using some name for the object, so a local, non-exposed name needs to be used. For convenience, they redefine jQuery as a variable in the scope of the anonymous function.

The pattern itself is called module pattern. It´s not specific for jQuery and it´s not strange but very helpful. It allows for hiding of the objects state and implementation. It also allows for priveleged methods (public methods with access to private data) and other good design principles.

Related

Module pattern that passes jQuery or different global

Is this pattern :
// Global module
var myModule = (function ( jQ, _ ) {
function privateMethod1(){
jQ(".container").html("test");
}
function privateMethod2(){
console.log( _.min([10, 5, 100, 2, 1000]) );
}
return{
publicMethod: function(){
privateMethod1();
}
};
// Pull in jQuery and Underscore
}( jQuery, _ ));
myModule.publicMethod();
I don't understand what is the purpose of passing global, if it is anyway global ?
Is this more efficient to have jQuery or other global "closer" not so far away in prototype chain ?
And if someone wants to use
jQ
That refers to jQuery
Why just don't do
var jQ = jQuery
In scope he/she wants to use it.
One reason to do this would be if you have multiple versions of jQuery on a page using jQuery noconflict, you could isolate this code from having to know about that or worry about it. You would just pass the correct version. If you want to use the $ shorthand, this could also be good to prevent conflict with other librarys such as Mootools that also use the $ symbol.
In general though I agree with you that it doesn't seem especially useful.
Update
That does in fact seem to be the reason for this particular useage. From the source you linked:
Here, we’ve wrapped our plugin logic in an anonymous function. To ensure that our use of the $ sign as a shorthand creates no conflicts between jQuery and other JavaScript libraries, we simply pass it to this closure, which maps it to the dollar sign.
and also
This variation of the pattern demonstrates how globals (e.g jQuery, Underscore) can be passed in as arguments to our module's anonymous function. This effectively allows us to import them and locally alias them as we wish.
So its used as a contrived example to show that you can alias globals if you prefer a shorter name.

How to write functions in 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.

function call with '$' as parameter

I have a script which contains the following piece of code:
(function ($) {
// ...
})($);
Can anyone explain how to read it?
Create an anonymous function
Let it take one argument which will be called $
Call the function immediately
Pass it one argument which is whatever the value of $ is in the outer scope.
If the $ in the outer scope changes (by having a new value assign to it) then the value for $ in the inner scope will be protected from the change (since it is a different variable).
This also provides a clean scope for all other variables declared inside the function (if they use var as they should).
'$' is a legal variable in JavaScript. It could have just as easily been someCrazyLongVariableName
It kind of defeats the purpose of encapsulating the $ sign into an anonymous function.
It's a self executing anonymous function that takes $ as argument.
In most of the cases, you use this markup to avoid js libraries collisions : say that you want to use jQuery and prototype in your project. Very nice, but they both use the '$' sign... how to overcome this?
// jquery code here
(function($){
alert($ === jQuery);// the $ is a shortcut to jQuery
})(jQuery);
// non-jquery code here - ex: prototype
alert($ === jQuery);// the $ is NOT a shortcut to jQuery ANYMORE
If you're not thinking about the $ in particular, the extract is creating a javascript function and calling it in a single statement.
I'm not 100% sure, but i guess that the 2 $ variables would be a different scope.
I found this page useful, if a little verbose: -
http://www.authenticsociety.com/blog/JavaScript_DollarSign
In summary, it's no different to calling the variable a, but should be avoided.

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