I have the following JS code, which uses jQuery:
var anArray=[];
var passIntoFun =100; // calculated value;
function ArrayIteratorFun(index, element, thirdParam){
// function code.
}
I want to call ArrayIteratorFun using .each construct, like:
$(anArray).each(ArrayIteratorFun(passIntoFun));
I could only call it like, by wrapping into a function:
$(anArray).each(function(i,e){ArrayIteratorFun(i,e,passIntoFun);});
is there any better way to write the code above?
Assuming your example is oversimplified and your function does not have access to the variable you wish to pass in as an argument (as one comment alludes to)...
The problem you have is that of pre-filling certain arguments (thirdParam in your case) of your ArrayIteratorFun. Sometimes you'll see this kind of technique called partial application or currying.
You happen to want to apply the third argument (leaving the preceding ones unfilled), which removes the possibility of using Function.prototype.bind. Bind is useful, but I often use the more flexible partial function from underscore.
With partial you can apply arbitrary arguments, by using _ in place of arguments that you want to apply/fill later:
$(anArray).each(_.partial(ArrayIteratorFun, _, _, passIntoFun));
The above ignores the first 2 arguments of ArrayIteratorFun (using underscores) and applies the value of passIntoFun to the third argument.
EDIT: I'm not aware of any way that jQuery provides of doing the same thing as _.partial. However if you are restricted to not using underscore (or a similar framework) then I recommend you check out the implementation of partial in underscore and this great article on the subject of partial application in javascript. These both provide ways of implementing using only plain javascript.
Related
What is the purpose of call and apply methods in the language?
It seems to be an example of anti-pattern which breaks OOP principles. Or it just presents multi-paradigm approach?
This example made me to ask this question.
In one place of application (a part of library) there is such a code
socket.emit = function() {
if (!socket.banned) {
emit.apply(socket, arguments)
}
}
In another part of application (self written) there is such piece of code
socket.emit = function(arguments){
data = Array.prototype.slice.call(arguments);
emit.apply(socket, data);
}
In the first place the object should not work if it is banned. But the second part knows nothing about library logic and works independently.
How this situations may be resolved? We use libraries to ease the most difficult parts.
Function.prototype.call exists for one purpose only, and this is to allow the function to be called with a specific value of this, i.e. the one that's passed as the first parameter.
Function.prototype.apply is the same, but with the added advantage that the array passed as the second parameter is split out into multiple parameters when the function is invoked. This is useful when you want to call a function that takes a variable sized list of arguments but you have those arguments ready in an array instead of as individual values.
Take, for example, Math.max. If I have a set of unknown size and I wish to find the largest there are two approaches:
successively compare each element against the current maximum until you find the largest
pass all of them directly to Math.max.
I can't call Math.max(a, b, c, etc) because I don't know how many variables there are. Instead I can call Math.max.apply(null, myArray) and that gets expanded to Math.max(myArray[0], myArray[1], etc).
NB1: in ES6 .apply isn't strictly required any more because you can use .call with the ... spread operator, e.g. Math.max.call(null, ...myArray).
NB2: this has nothing to do with breaking OOP principles.
I see sometimes js snippets that are using the $ in front of the argument ($argName).
function someName(arg) {
// some code
// using arg
}
function someName($arg) {
// some code
// using $arg
}
In this js example it works either way with or without the $ in front of the arguments. Can anyone explaine if it has any use?
The $ character is legal in JS identifiers, and is often used simply as a code convention to indicate that the passed parameter is already a jQuery object (as opposed to a native DOM element).
This serves as a reminder that it's not necessary to re-invoke the jQuery $(param) wrapper function on that parameter.
It's also used quite a lot in Angular JS code.
It's sometimes used to reference an object from another library , like JQuery or AngularJS , what you're talking about here looks like AngularJs's dependency injection to me
UPDATE
See this answer it might be useful
This a theoretical question:
Is there a generic name to refer to all those jQuery functions that don't accept functions as a parameter?
Such the index(), children(), height() ...
UPDATE:
If i know the name then I could make a question like this: "Can I pass a function to a "named" function?"
To give a little more detail, I have tried to pass a function as a parameter to jQuery's .index() method but it does not work:
textbox.closest('tr').index(function(){var index = $(this);});
All jQuery functions that take parameters can take functions. In JavaScript, functions are objects, and neither jQuery or vanilla JavaScript are type-safe. In other words, as long as the function accepts parameters, it will accept a function as one of its arguments.
Ergo, methods that do not accept any parameters are the only methods that will not accept functions.
EDIT:
If you want to get technical, then even methods that do not accept any parameters will still accept a function as an argument. Just as JavaScript isn't type-safe, it also doesn't actually enforce any rules regarding the function's signature, i.e. it doesn't check that the number of arguments entered matches the number of arguments defined. This is why you get a "null reference" error (if unhandled) instead of a "no function [function name] takes the arguments [arguments list]". This is also why you can pass an unlimited number of arguments to a function, even if it only takes one, two, or none.
UPDATE:
With regards to my solution to your original question, I would like to clarify by adding that jQuery is a solid language in that it often will simply return null when it is passed invalid arguments (but it will not error out when being passed an incorrect number of arguments). JavaScript is the same in many situations, but, as I implied and common sense would dictate, it would be nonsensical to pass too many or too few arguments to a method, regardless of legality.
With regards to your updates and your comments, I think that you're misunderstanding the fundamental use of jQuery's .index() method. When used properly, this method is called on a collection of elements and has a selector (or an element to match) as a parameter, and returns the index of the first occurrence of an element that satisfies the given selector, or matches the given element.
Update:
From your updated example, I can see that I was correct in thinking that you are misunderstanding the use of the .index() function a little bit. The function takes either a selector or an element, but you passed a function that doesn't return either. Here is what you would need (using your existing syntax):
textbox.closest('tr').index(function(){ return $(this);});
OR (more simply):
textbox.closest('tr').index($(this));
To add a bit more detail (and, perhaps, better answer your initial question), you could also do something like this:
function getOnlyParagraphElements() {
return this.tagName === "p";
}
var collection = $("body").find("*");
var firstParaIndex = collection.index(getOnlyParagraphElements);
This was only an example (and yes, I know that I could just use jQuery to get paragraphs), but the concept is the same - this is how you make your own selector.
Also note that in your examples, you are always checking against a one-item collection, meaning you will only get either the value 0 or the value -1 (if the element doesn't match the selector/passed in element). If your goal is to get the index of the element that you are calling the method on relative to its siblings, then you need only call the method without supplying any parameters.
I have a gallery that I am trying to integrate in my site. I am replacing a and then I want to call the galleries function "function loadGal($)" so the gallery will be rebuilt. But I don't know what kind of parameter to send to it.
Before I changed it, it was called inside "jQuery(document).ready(function($) {"
I just tried to do something like this:
jQuery(document).ready(function($) {
loadGal($);
});
it works fine but I don't know what is the dollar...
The $ is just the name of the parameter. It is nothing special. $ is a valid character of variable names in JavaScript.
However it is often used by libraries such as jQuery or Prototype as it is probably the most characteristic one-letter variable (j or p don't stand out that much) (meaning it is easy to spot and easy to use as you only have to type one character).
The value passed to the ready handler, is the jQuery object (emphasis is mine):
When using another JavaScript library, we may wish to call $.noConflict() to avoid namespace difficulties. When this function is called, the $ shortcut is no longer available, forcing us to write jQuery each time we would normally write $. However, the handler passed to the .ready() method can take an argument, which is passed the global jQuery object. This means we can rename the object within the context of our .ready() handler without affecting other code
but you can name the parameter however you want. You could also write:
jQuery(document).ready(function(foobar) {
loadGal(foobar);
});
Update: And now that I understood the real question ;)
$ is the jQuery object, so you can write:
loadGal(jQuery);
But note that loadGal might not work if it has to work on the DOM elements and you call it outside the ready handler.
Pouring over the release notes regarding jQuery 1.4, I came acrosss $.noop() which is:
Description: An empty function. (added in 1.4)
You can use this empty function when you wish to pass around a function that will do nothing.
Perhaps I'm missing something profound here, but what exactly is a practical use of passing around an empty function?
Code examples appreciated.
This function was proposed due to performance issues on embedded systems when using $.ajax, reported on the jQuery-Dev mailing list. You can see the thread.
Basically, they preferred to introduce and use this single empty function, rather than declaring empty anonymous functions all around.
Now this function is internally used in the ajax, event and offset modules.
You can give a look to the commit when it was introduced also.
If you have a function that accepts a function as a parameter, and you don't have any code to give it, you can pass $.noop.
I can't think of any such cases in jQuery where the parameter isn't optional in the first place, though.
Unlike writing function(){}, passing $.noop will not create a new function instance, saving a bit of memory. However, if whatever you're passing it to modifies the function object (eg, funcParam.id = 2), passing $.noop will mess things up.
Real World Example (well almost):
jQuery.fn.myAwesomeAjax = function(url, complete) {
return jQuery.ajax(url || this.url)
.complete(complete || jQuery.noop);
};
Use it instead of function (){}
Probably if some bad API requires a function as a parameter, and you don't want to do anything in it, this would be a framework-supported way of making that obvious.
I use a couple of plugins which require callbacks, but for some parts I don't actually want to use a certain callback. So, I put in function() {}.
noop is defined in the jQuery source as
noop: function() {}
so it will fit anywhere you'd use a blank function, such as the above example.
The only logical reason is if you're calling a function that does something AND calls another function, and you want the higher-level function to do its thing without calling a parameter function.
Most of the jQuery functions optionally take a parameter function, so you don't have to pass one in. Maybe there's one or two where that's not the case -- or maybe it's to assist developers with their custom code that behaves like this.
If a function requires you pass a function as an argument maybe? It's shorter to say do_something($.noop) than do_something(function(){}).
Although not by much...
...6 characters...
...yeah, that feature looks quite useless actually.
It can be useful if you have a function that supplies functions to other functions.
Example: You have a List of data. Each item has a Button that does something. The "something" can be different for every item. You have a "FunctionFactory" that takes in the item and returns a function. If you don't want the button to do something for whatever reason, then the cleanest way could be to return an empty function, as that way you know that your Factory ALWAYS returns a function.
I don't have a concrete example for jQuery, but I guess this could come in handy when used in an .each or .map block.
It's purely a convenience/replacement for function(){} in the context of where callbacks are required - I don't think I'll be using it anytime soon.
I bet the jQuery team had quite a laugh when they dropped it in though, also serves a comedic purpose.