I've been shown how to call variable javascript functions by using window[]().
Is it possible to call variable jQuery functions? If so, how?
Usually, I only need a ternary to flip a visible switch, and it would be very convenient to smush many lines of code into 1. For example, inside an $.aja() success:
if(msg.length > 0){
$("#gridViewContainer").slideDown()
}
else{
$("#gridViewContainer").slideUp()
}
This is probably a bad example since a boolean can probably be passed to slide() or something, but I'd like to use the concept in the linked question above.
This did not work for me:
$("#gridViewContainer")[((msg.length > 0)?'slideDown':'slideUp')]()
jQuery functions are still just JavaScript functions, so the same rules apply to them as any other JS functions.
You can call methods of an object objectVar as follows:
objVar.method();
objVar["method"]();
var methodName = "method";
objVar[methodName]();
Your question mentioned using window[]() - that applies to global functions, since they are essentially properties of window (if running JS in the browser, of course).
In the case of jQuery, you can therefore do this:
var methodName = "hide";
$(someSelector)[methodName]();
$(someSelector)[anyJSExpressionThatReturnsAStringThatIsAjQueryMethod]();
EDIT: I just saw the new version of the question. The line of code shown with the ?: operator selecting the method name should give the same effect as the if/else. I've used similar code myself with no problems, and it works fine in the fiddle that Jason P provided. Note that since your motivation here seems to be about making the code shorter you can omit all of the parentheses from the expression in the [] and just do this:
$("#gridViewContainer")[msg.length > 0?'slideDown':'slideUp']();
...or even omit the > 0 part since msg.length will be truthy when non-zero:
$("#gridViewContainer")[msg.length ?'slideDown':'slideUp']();
Related
I've noticed that when creating functions in Java Script ES5 you can specify parameters that will not necessarily have to be used, e.g.
function foo(uselessParam) {
// code that will not use uselessParam
}
If I'm correct - if I wont use this parameter within my function I can call that function without passing that parameter and "foo" will still run without throwing errors. This gave me idea to use fat arrows in ES6 like this:
let foo = f => {
// code not using f parameter
}
"f" in my opinion points that this piece of code is a function in more intuitive way than "()" I like doing so, even that "()" suppose to be used when no parameters are specified.
Here is my question: is there any scenario when using empty parameter instead of no parameters passed at all could be a problem? Could using this pattern cause any problems? What do you think?
The function will have a different .length, so if any introspective code is using that property for anything, you may see unexpected results.
I often find that I write IF statements which immediately reference the value of the conditional statement. For example, let's say I need to check to see if a string matches a pattern:
if (mystring.match(/mypattern/) {
var mymatch = mystring.match(/mypattern/)[1];
...
};
I suspect that what I'm looking for doesn't exist, but I've wondered whether you can reference the conditional statement's value within the if block, the way you can reference "arguments" within a function. In many cases, of course, I can rewrite it like this:
var mymatch = mystring.match(/mypattern/)[1];
if (mymatch) { ... };
But that's often not possible if there's a series of methods called. For example:
var mymatch = $('.myclass')[0].text().match(/mypattern/)[1];
... that would throw an exception if there were no item [0] on which to call .text(). Is there some convenient shorthand I'm missing out on? Or a better way to organize things? Just curious, really — I'll go on living if the answer is no.
In cases where relevant you can use the fact that the assignment operator returns a value in JavaScript, so for instance you can write things like:
if (assignedTest = testedValue) {
//value of assignedTest is now available
//and conditional will only be executed if true
This could be used if the RHS was compatible or properly set-up but it's also a huge readability concern since it's very easy to confuse the assignment = with comparison ==/===.
If you were particularly motivated to pursue this you could extract this type of functionality into a function that would behave in a reliable way: such as assigning the result of a closure to a named variable, and you could further tune the behavior to do other things (such as optionally evaluating to a different value within the test). Ultimately it would primarily be making a simple structure more complex though.
I am using a jQuery plugin and running it through the Microsoft Ajax Minifier. My scripts work well for me, but now I am running into an issue with this plugin. The issue is that the plugin calls a function by its name using a string:
var s = (getCachedSortType(table.config.parsers, c) == "text") ? ((order == 0) ? "sortText" : "sortTextDesc") : ((order == 0) ? "sortNumeric" : "sortNumericDesc");
Note the "sortNumeric" and "sortNumericDesc". This calls these functions:
function sortNumeric(a, b) {
return a - b;
}
function sortNumericDesc(a, b) {
return b - a;
}
This is the only location these functions are called so the IDE VS2010 doesn't think that the functions are being called from anywhere... They are conditionally via the code above.
**Here is the Problem**
When this gets minified, the string name of the function stays, but the function gets removed because it does not thing its getting referenced.
Is there any way to adjust the settings minifier to not do this?
I have also seen it change the names of the functions so
function testFunctionName(a,b)
Would become
function a
This would also cause a problem for situations like mine...
Please note, that I know it is bad code design to hard code function names like this. Like I said it is a plug-in that I am using. I would accept a solution that would call the function out right instead of by string, but I am always hesitant to modify plug-ins.
From documentation:
-evals:(ignore|immediate|safeall) specifies how eval statements are to be treated. This is an important switch to be aware of. By default Ajax Minifier will ignore any eval statements, which can break your minified code if it contains eval statements that reference named local variables or functions. This is because by default Ajax Minifier will also rename local variables and function, but it doesn’t modify the text passed to the eval function, so those references may break. If you minify code and it stops working properly, check the code for eval statements. If there are any, try specifying one of the other two –evals switch options. The “immediate” options will not rename any variables or functions within the same scope as any eval call; the “safeall” option will not rename any variables or functions not only in the same scope as any eval call, but also in any parent scopes. This will seriously impair the minification of your code, but should ensure that any calls to the eval function will work as expected. The default setting is ignoreall.
Then try -evals:immediate and if your code is still broken you have to use -evals:safeall (even if this will make your JavaScript files bigger).
UPDATE
If you're not using eval then you have to skip function renaming at all:
-rename:(all|localization|none) specifies whether or not to automatically rename local variables and functions. Global variables and functions are not automatically renamed, nor are property names. If “localization” is specified, only variables that do not start with “L_” will be renamed. The default value is all.
Just add -rename:none.
Use -unused:keep switch to retain unused functions. This, naturally, will prevent minifier from removing really unused code.
Use -rename switch to assign permanent names to functions that you call by name.
Excuse me first. because i don't know this is question is valid or not. i if any one clear my doubt then i am happy.
Basically : what is the different between calling a method like:
object.methodname();
$('#element').methodname();
calling both way is working, but what is the different between, in which criteria make first and second type of methods. is it available in the core javascript as well?
In case if i have a function is it possible to make 2 type of method call always?
Can any one give some good reference to understand correctly?
Thanks in advance.
The first syntax:
object.methodName();
Says to call a function, methodName(), that is defined as a property of object.
The second syntax:
$('#element').methodname();
Says to call a function called $() which (in order for this to work) must return an object and then call methodname() on that returned object.
You said that "calling both way is working," - so presumably you've got some code something like this:
var myObject = $('#element');
myObject.methodname();
This concept of storing the result of the $() function in a variable is commonly called "caching" the jQuery object, and is more efficient if you plan to call a lot of methods on that object because every time you call the jQuery $() function it creates another jQuery object.
"Is it available in the core javascript as well?" Yes, if you implement functions that return objects. That is, JS supports this (it would have to, since jQuery is just a JS library) but it doesn't happen automatically, you have to write appropriate function code. For example:
function getObject() {
return {
myMethod1 : function() { alert("myMethod1"); return this; },
myMethod2 : function() { alert("myMethod2"); return this; }
};
}
getObject().myMethod1().myMethod2();
In my opinion explaining this concept in more depth is beyond the scope of a Stack Overflow answer - you need to read some JavaScript tutorials. MDN's Working With Objects article is a good place to start once you have learned the JS fundamentals (it could be argued that working with objects is a JS fundamental, but obviously I mean even more fundamental stuff than that).
The difference is very subtle.
object.methodname();
This is when JavaScript has the object at hand.
$('#element').methodname();
If you are using jQuery, you are asking jQuery to select the object that has the id of #element. After that you invoke the method on the selected object.
I'm using mootools:
I can't figure out how to use a variable when using an addEvent.
I want to use a for next loop to set values in a loop:
for (x=0;x<num;x++){
var onclickText = 'function (){onclick="addPageMoveEvent('+x+'"); }';
$('pageNum'+x).addEvent('click', onclickText);
}
>
I've search forums but not found any help.
Any help would be great.
Thanks
The addEvent method in MooTools accepts two arguments:
myElement.addEvent(type, fn);
Arguments:
type - (string) The event name to monitor ('click', 'load', etc) without the prefix 'on'.
fn - (function) The function to execute.
It does not take a string and passing a string such as "myFunction()" or "function() { myFunction(); }" will not work.
Since you are inside a loop, and the variable x will share the environment, you need to wrap its value inside another closure. One way is to use an additional closure:
$("pagenum" + x).addEvent("click", (function(value) {
return function() { addPageMoveEvent(value); }
})(x));
See all questions on StackOverflow regarding this particular problem of creating closures within loops.
Also worth checking out is this MDC article - Creating closures in loops: A common mistake
Warning: this first example will not work! Read on for an explanation.
You are confusing onclick HTML syntax with the MooTools addEvent. Try
for (var x=0;x<num;x++){
$('pageNum'+x).addEvent('click', 'addPageMoveEvent('+x+');');
}
This is simpler and cleaner, but might still not do what you want. This code will call the function addPageMoveEvent every time the link is clicked... is that what you want?
Since MooTools doesn't allow the above method, you must use the following:
A programmatically more interesting and less hazardous way to do the same would be:
factory = function (x) { return function() { addPageMoveEvent(x); }; };
for (var x=0;x<num;x++){
$('pageNum'+x).addEvent('click', factory(x));
}
This uses a factory for creating closures that hold your values of x... rather complex code, but it's the purist way. It also avoids using the scary eval that occurs because you feed addEvent a string. (It seems that MooTools doesn't like the other option anyway.)
That a use case for mootools pass method.
for (x=0;x<num;x++){
$('pageNum'+x).addEvent('click', addPageMoveEvent.pass(x));
}
Pass internally creates a closure that holds x in the his scope, so when the click event is fired it has the right value cause its not the same from the for loop.