Argument passing into IIFE - javascript

Do anyone can explain and prove which one of examples is "more correct"?
A: pass object as an argument
(function($){
$.doStuff();
})(jQuery);
B: retrieve object within the function
(function(){
var $ = jQuery;
$.doStuff();
})();
I really like B because of its readability. Only technical difference between A and B is that B has to lookup one more scope. I consider this as marginal difference so why is "recomended" the A way?
Note that the jQuery is just example. Important is the nature of the problem: Pass as argument or retrieve within the function?

The second way will only work if the name of the jQuery library is really "jQuery". It's possible (though unusual) to call .noConflict() like this:
window.banana = jQuery.noConflict( true );
Then, your first example would still work:
(function($) {
$.doStuff();
})( banana );
but your second example would fail (as written). Of course, you could similarly hard-code the name "banana" into the second one too, but if that function isn't directly under your control, you can't; plus it's a "DRY" violation.
Imagine that you've got an initialization function being loaded in a separate JavaScript source file; perhaps it's a 3rd-party script. If you want to call that function at initialization time, you'll have more flexibility if the function takes the jQuery reference as a parameter instead of just making the assumption that the global symbol is anything in particular.
alienInitializationFunction( banana );
will still work, in other words.

Both are equivalent, but I like the first example (passing as an argument) more as it saves you one line of code. That also means that your function does not contain unnecessary logic.

Related

What JavaScript concept allows for the same name to be both a function and an object?

I've been using JavaScript for a few years now in web design/development, and everything I know has been self-taught (I was a design major and hobbyist front-ender turned full web developer in pursuit of my career). With that background, I discovered something that I want to learn more about and have no idea what it is called, how it works, or that it may even be something extremely simple.
I've tried to search for more information about this (to prevent myself from needing to ask this), but it's difficult when I'm not sure what it's called that I'm even looking for...
I noticed in a few JavaScript libraries that I use that a variable name can be both a function and an object. For example, the jQuery library uses the name "jQuery". When logged using typeof jQuery it is a function, and typeof jQuery() is an object. What is interesting to me is that initial thought would suggest that jQuery() would be a function but it's actually an object.
//jQuery:
ƒ (a,b){return new r.fn.init(a,b)}
//jQuery():
r.fn.init {} //Expanding this reveals functions inside of __proto__ (which is obviously a clue, but I need more info)
When I try to do something like this I end up overwriting the name (as I would expect):
//Declare an object:
var planetEarth = {
'sky': 'blue',
'grass': 'green'
}
//Now overwrite the object as a function:
function planetEarth(){
console.log('inside of a function now');
}
This is understandable within the realm of JavaScript, so my question is how does a library like jQuery pull off having both at the same time?
Ultimately (using the above example) I would like to be able to do something like this:
planetEarth().sky; //"blue"
So my roundabout question is simply what is this called?
And a follow-up of where can I learn the basics of accomplishing this?
I've found resources on object-oriented JavaScript and classes, as well as prototypes, but I'm not sure if either (or both) of those concepts are what this is. All of the articles I've found aren't starting at the beginning and seem to always jump into unnecessarily complex examples. I'm not looking to make a giant library- I just want to get some more experience at the very basic level. Again, this could be embarrassingly simple and I've just never come across the concept before, so I appreciate being pointed in the right direction, thanks.
Every JavaScript function is also an object, just as every array is also an object. I don't think there is a special name for this, it's just how the language works.
You may be confusing two different things: what a function returns when you call it, vs. the function itself. Take your example:
planetEarth().sky; // "blue"
This code does not rely on the function planetEarth being an object and having any properties. You're calling the function, so to make this code work the function would need to return an object.
Because a function is an object, you can also set properties directly on the function itself. The code below uses both of these features. This version of planetEarth() returns an object with sky and grass properties, so it works as in your example: you call the function to get an object with those properties.
The code also sets an exists property directly on the function, and you can access that property without calling the function:
function planetEarth() {
// Return an object when this function is called
return {
sky: 'blue',
grass: 'green'
}
}
// Set a property directly on the function itself
planetEarth.exists = true;
// Test accessing the function's property
console.log( planetEarth.exists );
// Test accessing a property in the object that the function returns when called
console.log( planetEarth().sky );
jQuery makes use of both of these facilities. jQuery is a function that you can call. It returns a value commonly called a "jQuery object". That object has properties and methods, such as jQuery('#foo').show(). It also has "array-like" properties that you can access as you would any array, e.g. jQuery('#foo').length and jQuery('#foo')[0]. The jQuery function adds those properties to the value it returns.
At the same time, the jQuery library adds other properties and methods to the jQuery function itself. You access without calling the function, e.g. jQuery.ajax({...}).
A couple of other notes to help you understand the jQuery code. First, download the uncompressed version of jQuery. It looks like you are studying the compressed version, which has shortened names that won't make any sense.
Also, if you are wondering what jQuery.fn is, it is simply an alias for jQuery.prototype. Whenever you see jQuery.fn you can mentally substitute jQuery.prototype; learn how JavaScript prototypes work and you will understand jQuery.fn.
And now you may wonder why jQuery.fn exists at all. Why not use jQuery.prototype directly like other JavaScript code that uses prototypical inheritance? In fact, you could, and it would work the same as jQuery.fn. But the very first version of jQuery, back in 2006, didn't work this way. jQuery.fn was its own separate object, and every time you called the jQuery function, it copied all of the methods and properties from this object into the value it returned.
As you can guess, this was rather inefficient, so jQuery was changed to use .prototype so it could return an object that inherits all the methods such as .show() and .hide() instead of copying them all one by one. At the same time, jQuery.fn was kept around as an alias for jQuery.prototype to avoid breaking existing code.
This is a silent answer...
function f() {
return {};
}
console.log(typeof f, typeof f());
This is how jQuery does it. f is a function but when it gets called it returns an object.
Interesting part: function is also an object. f instanceof Function and f instanceof Object are both valid. So, you can call a variable as a function and / or assign some properties because it is also an object.
f.test = 123;
First-Class Objects
In Javascript, functions are first-class objects. This means that functions are just another kind of object. You can put a function in a variable, you can return a function, you can make an array of functions, and all that. Functions are objects.
Consider a slight change in your attempt:
//Declare a function:
function planetEarth(){
console.log('inside of a function now');
}
// Now add fields to it, since it is also an object
planetEarth.sky = 'blue';
planetEarth.grass = 'green';
// Test stuff
planetEarth(); // works
console.log(planetEarth.sky, planetEarth.grass); // works
You mention that you would like to use planetEarth().sky, but observe that while planetEarth is a function (and an object, as I said), planetEarth() is the result of calling planetEarth with no parameters. Therefore, whether you can or can't do planetEarth().sky does not depend on planetEarth as an object having the sky field, but rather depends on whatever you return from planetEarth having that field.
Bonus: did you know that functions can be declared very much like "normal" variables? See below:
// Both lines of code below are identical:
function myFunc() { ... }
var myFunc = function() { ... };
Perhaps looking at the code above will help you clear the confusion. The function is myFunc. myFunc() is simply the act of calling that function. If typeof myFunc() gives function, it is just a coincidence that the object that myFunc returned happened to also be a function.
jQuery is a function. Properties can be assigned to a defined function.
function planetEarth(options){
console.log('inside of a function now', options);
return window["planetEarth"];
}
var planetEarthOptions = {
'sky': 'blue',
'grass': 'green'
}
for (let prop in planetEarthOptions) {
planetEarth[prop] = planetEarthOptions[prop];
}
window["planetEarth"] = planetEarth;
planetEarth("selector");
console.log(planetEarth.sky);
console.log(planetEarth().grass);

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);
})();

Javascript/jQuery function arguments

Newbie jQuery / Javascript question here
I see functions written in the following fashion:
some_function = function(event) {
}
My question is: What is meant by that event argument? Is it optional? What if I want to have two additional parameters, X and Y, what would the signature look like? When I call the function now, I can just call it like some_function(); and it works fine (which leads me to believe that it's optional). However, how will that change when I have two additional arguments like X and Y? Can I just call it like some_function(myX, myY) ?
Thanks!
There are two ways to instantiate a function in JavaScript. They both look the same, but their meanings aren't quite the same.
What you've posted is a function instantiation as part of an expression in the language. In that form, the syntax is
function name ( p1, p2, ... ) { body }
The "name" and the parameters are optional; the keyword function and the parentheses are required. (There are some obscure issues with using a name in this case, in some browsers; it's getting to be less of a problem.)
The effect of that is to create a new function object. The reference to the object participates in the expression just like any other value (well, like any other reference to an object). Because it's a function, the reference can also be used to call the function and cause its code ("body") to execute, just like you'd expect. (It wouldn't be much of a function if you couldn't!)
The other way a function can be instantiated is with a function declaration statement, which looks, surprisingly, exactly the same (except that "name" is required). The difference involves where exactly in your code the keyword function appears:
If the keyword function is the first thing in a new statement, then you've got a function declaration and the "name" is required. The statement is not an expression statement in this case, and the only thing the statement does is instantiate the function and bind a reference to the function to "name" more or less as if "name" were a local variable (or global if in the global scope).
If the keyword function appears anywhere else in an expression (either an expression statement, or an expression buried inside some other context, like the top of a for or while loop statement), then it's a function instantiation expression.
Now, regardless of how a function is "born", once you've got a reference to the function you can call it and pass as many parameters as you like.
I don't know personally how the trend started, or whether it's even something that should be considered a trend, but it's fairly common to see local functions instantiated with code like this (and like what you posted):
var some_function = function( arg1, arg2 ) {
/* some code */
};
That's an example of a function instantiation in an expression. The net effect is that the symbol "some_function" is bound to the newly-created function. There are slight nitpicky differences, however, between the way that name is bound to the function from the (almost) equivalent function declaration:
function some_function( arg1, arg2 ) {
/* some code */
};
One simple reason that the second way (function declaration statement) is a little better is that the name of the function will show up in stack traces. Of course, one could achieve that with the redundant-looking:
var some_function = function some_function( arg1, arg2 ) {
/* some function */
};
I don't really know why you'd want to do that, but it'd work, except in some naughty environments.
That code snippet is a little vague, however I can answer, in general, your questions.
The event argument, in the code you provided, is just what that function will use to reference the first parameter that is passed to the function from whatever-other code calls it. For example, if you had code that called your some_function function, and passed it a string "hello world!", the call would look something like:
obj.some_function("hello world!")
Inside of the some_function function, the variable event would contain "hello world!". Also, you could change your some_function signature to be: some_function(blah) and it would be all the same, you would just use blah to reference the parameter instead of event. The variable name you choose for parameters is entirely up to you, though you want to make sure you don't use language-reserved names (like in, for, continue, break, etc)
Technically all parameters are optional for a JavaScript function, unless the internal code of the function enforces the parameters (i.e. it may return or throw an error if a parameter is missing.
#Pointy answered the other point I was going to make...that the code you provided is defining that function as an expression. I use that syntax when I'm creating a function that is an attribute of an object (which is why my above code has obj. at the beginning.

Code convention for function and callbacks

So I started learning javacript and I've noticed that the coding convention for functions and callbacks is something like this (this is a jQuery example but I've seen these everywhere):
$.getJSON('some/url.json', function(a) {
// do stuff with a here
});
Coming from other languages, I would usually write the above as this:
function myFunction(myVar){
//do stuff with myVar here
};
$.getJSON('some/url.json', myFunction());
Why is the former usually the preferred way of writing in JS, instead of the [probably more readable] latter?
There are plenty of good reasons to use the second, more explicit, format (assuming you fix the issue listed in the comment), including:
reusing the function passed as a callback
giving that function a definitive name to make it easier to debug
making sure that function is noted as something important in your system
separating out that functions because it's simply too long to comfortably declare in place
But the first format, with an anonymous function passed as a callback is short and sweet. If you don't need to reuse the function, if it's relatively short, and if it's not of high importance in your system, it can be really useful to declare it exactly where you use it. You avoid adding another variable to your scope, and you make it entirely clear exactly what that function is for.
It's not the preferred way. You can do anything you want. However, if you need to reuse the function, then you need to do your second option, or alternatively the following, for code reuse:
// in some accessible context/namespace
App.myCallback = function(a){
...
};
// somewhere else
$.getJSON('url', App.myCallback);
Your first example is what is referred to as an anonymous function or block. They are used when they'll only be called once. The second example is when you'd use the function many times... it would be a lot of wasteful typing if you repeated the anonymous block over and over.

Best approach to avoid javascript's “this” mistakes in XBL

Talking about XBL is not exactly talking about javascript. So I'll create this question that's related to this one, but now about XBL, where I'm not the creator of the root javascript code, but just of the methods and event handlers inside the bindings.
--
In some cases, the this keyword may not refer to the object I expect it to. (recent example: in an key event, in my XBL)
What's the best approach to avoid this kind of mistake?
For now, I'm using always the getElementById (or $.fn from jQuery), but I'm not sure if it's the best approach.
--update
A little bit more details:
Within a XBL method the only way to access the element that was defined in the Xul file (the GUI description file) without using "this" (as it may not be the "this" I expect) is with getElementById, and this makes the code not reusable, so I'm looking for alternatives..
As you've heard elsewhere, the problem is that the this parameter isn't necessarily the object you first thought of, especially when you're talking about event handlers and the like. The best way I found is to write a small function that will bind some object as the this variable and return another function that uses the binding to call the original function.
Take a look at this code:
var bindFunction = function(self, f) {
return function() {
return f.apply(self);
};
};
var foo = function() {
alert(this.hello);
};
var bar = {
hello: "Hello there"
};
var boundFoo = bindFunction(bar, foo);
boundFoo();
What I have is a function called bindFunction that takes an object (called self) and some function, and returns another function that will call the passed-in function applying the self object as the this variable.
The rest of the code is just some test code: a foo function that will alert this.hello, a bar object with a hello member, and how you can bind foo with bar.
In essence, I've taken a function that accepts no parameters and generated another function that will ensure the first is always called with the correct this variable. Ideal for event handlers.
(Sorry, but I know nothing about XBL, so I hope this will be of use.)
If there's not a best answer, a good approach could be use javascript files instead of XBL for the implementation. Looking the Xulrunner source code, looks like most code does this.
But I still would like to use XBL, if there was a way to work fine with it..

Categories

Resources