I have a Javascript method that's called deleteObjectsDependingOnX(objects, X), is it conventional to have the order of parameters as objects first and then X, or the reverse?
This is more a question on what the convention is in Javascript. I believe, in C++, the convention is to do the reverse, but wasn't sure what people do in Javascript.
I think there are no conventions about such things in JavaScript.
If X is a callback function, then putting it last seems more common and leads to (IMHO) easier to read code like this:
deleteObjectsDependingOnX(objects, function(o) {
// return true if o should die, false otherwise
});
The "callback at the end" is pretty common jQuery, see $.each and $.grep for examples.
Of course, setTimeout puts the arguments in the other order so the time value can get lost:
setTimeout(function() {
// Do a bunch of stuff and things.
}, 500);
OTOH, if you use a named function rather than an anonymous one, it looks okay:
setTimeout(doStuffAndThings, 500);
So I think the real answer is "it depends". If you're expecting anonymous functions more often than named ones, then putting the callback at the end will make for (IMHO) easier to read code.
Related
A colleague advised me to add "use strict"; to the top of my JS code to highlight any gaps in my definitions and potential reference errors, etc. I am very happy with it because it has identified several pieces of code which might have been a problem down the line.
However, another colleague advised me that when calling functions which take multiple arguments, it can be helpful to name the arguments as they are specified, especially if it's something like a bunch of booleans. To illustrate, here's a couple of function calls:
logData(data, target, preserveLog=true, changeClass=false, wrapLine=false);
...is a whole lot clearer than:
logData(data, target, true, false, false);
But "use strict"; hates this. everywhere I've done this, I get a reference error in the console. It still runs fine, as would be expected, but the console is now cluttered with all these apparently non-defined references.
Does anyone know if there's a way around this so that I can keep my coding conventions which my colleagues appreciate, or am I going to have to either stop using "use strict"; or go through all my code and remove the names of arguments?
Thanks.
However, another colleague advised me that when calling functions which take multiple arguments, it can be helpful to name the arguments as they are specified, especially if it's something like a bunch of booleans.
This is terrible advice!
Javascript doesn't actually support passing arguments by name this way. Each of the arguments you pass "by name" is actually being treated as an assignment to a global variable with that name, and "use strict" is correctly identifying this as an error.
If you want to be more clear about what values you're passing, assign the values to real local variables and pass those, e.g.
var preserveLog = true;
var changeClass = false;
var wrapLine = false;
logData(data, target, preserveLog, changeClass, wrapLine);
If you really wanted to keep using your original pattern, you could even assign to those variables in the function call, so long as you declare them as local variables first:
var preserveLog, changeClass, wrapLine;
logData(data, target, preserveLog=true, changeClass=false, wrapLine=false);
(With a hat-tip to dav_i for this answer, which I based my recommendation off of.)
Duskwuff has already provided an excellent answer and I won't add anything to that, other than to say I fully agree with it, but he didn't mention any conventions that arose due to ES6.
In ES6, you still don't have named parameters, but you have the next best thing, which is Object destructuring assignment.
This allows us to pass what appears to be named parameters, but are really just destructured object properties of an object that is never directly used.
In the context of the example you provided, it would look something like this:
logData({data, target, preserveLog:true, changeClass:false, wrapLine:false});
Where the function is defined as:
function logData({data, target, preserveLog, changeClass, wrapLine}) { ... }
I've seen a lot of libraries that prefer this calling convention where ES6 is available, and it's very convenient too because the order of the parameters is also no longer important.
Why would you use a jQuery plugin over a traditional javascript function? The only difference I see is you need to pass in a jQuery object into the js function... other that that, I don't see a huge difference, as it seems both can accomplish the same thing in similar steps:
$(document).ready(function () {
$('p').jQuery_greenify();
greenify($('p'));
});
$.fn.jQuery_greenify = function () {
this.css("color", "green");
};
function greenify (el) {
el.css("color", "green");
}
I also find namespacing to be easier with javascript functions:
var mynamespace = {
greenify : function (el) {
el.css("color", "green");
}
}
mynamespace.greenify($('p'));
Usually, usefulness of JQuery functions is in chaining them. Just like you want to call:
string.substring(2, 5).startsWith("lol")
instead of
Util.StartsWith(Util.substring(string, 2, 5), "lol")
It's easier to read that way. In fact, I think that second function might still need a "return this" to be useful?
It may depend on the context - some operations are very much tied to an element or set of elements, while others just make more sense standing on their own - thus, your approach of namespacing would be just fine. It's partially coding style.
A disclaimer - I'm not as experienced with writing JQuery plugins, this is just my general observations based on JS language design.
Always a jQuery object
When using a plugin as you said (it is really an object prototype) You are sure that this will be a jQuery object since you cannot call it without a jQuery object except if you make your way around with .call, .apply, .bind and etc.
Meanwhile, you can pass anything to a function, so the argument may not be a jQuery object and will throw an error.
Readability when chaining
You can chain function with both method, but let be honest, with a jQuery prototype, it is prettier :
$.fn.jQuery_greenify = function () {
return this.css("color", "green");
};
$('div').jQuery_greenify().append(...);
//VS
function greenify (el) {
return el.css("color", "green");
}
greenify($('div')).append(...);
Scope
When adding a function to the prototype, no matter which scope you are, it will be accessible everywhere. That allow you the create a certain closure :
(function(){
$.fn.jQuery_greenify = function () {
return this.css("color", "green");
};
})();
$('div').jQuery_greenify(); //Work
//VS
(function(){
function greenify (el) {
return el.css("color", "green");
}
})();
greenify($('div')); //Undefined is not a function error
The original usefulness of jQuery was to provide a consistent API to things such as DOM manipulation and AJAX - things which [older] browsers implemented very differently. It would take 20+ lines of code to do what can be done with 1 - 2 lines with jQuery. It abstracted away all of the inconsistencies so you could just focus on coding.
Then, John Resig's worst nightmare happened and people now think jQuery is a language, almost separate and independent from Javascript. </rant>
Today, most browsers have adopted standards and you don't have to worry so much about inconsistencies unless you are trying to support < IE9. You can use something like underscore to help take advantage of newer javascript features (with backwards compatability for things which are still inconsistently implemented even in today's browsers).
Regarding plugins, the advantage is having a consistent way to implement reusable code. For example, I kind of disagree with how you created a namespace (not really, but I would have done it differently).
Point is, it's all javascript. Learn javascript. If it's easier and quicker to do it without using a library, by all means do it! Pay attention to the community and try and use techniques which have been adopted by others... even if it occasionally means using a library.
NOTE: If someone puts jQuery under the "languages" section on their resume, throw it in the trash.
Suppose I have a function which returns an object :
getMyObject(){
//do stuff here
return object;
}
Is it bad practice to call a method (that doesn't return anything) on the function name itself:
getMyObject().method();
instead of assigning a variable to the return object and then calling the method on that variable :
var returnedObject = getMyObject();
returnedObject.method();
I am working with an html page that has many nested frames, and I have access to a function that returns one of these frames. The frame might be used several times within other functions in my script, and I was wondering if it would be ok for me to access the frame in the way asked above, or if it would be better to declare a global variable.
*EDIT: * Ahh I haven't gotten a chance to use jQuery. Good to know!
Yes, this is perfectly OK. jQuery for example uses this as well. It returns objects on which you can call methods immediatley. This is called chaining.
In your example, method chaining is the better practice IMHO. If a function returns an object, upon which you want to call a method, but you do not need to reference that object after calling that method, don't assign it to a variable.
Also, jQuery code does this all the time(1):
$('#foo').on('click',function(){});
/\ \\
|| \\
|| \\
function call returns jQ object <============|
\\ ||
\\call method "on" upon _||
(1)To clarify: I do not claim that all jQ methods return an object .attr() or .prop() don't. What I mean by "all the time" is actually that the scenario the OP describes is very common in jQ code (function call, invoke method on returned object):
var someString = $($('.foo').get(0)).attr('id');//tricky little bugger, this :)
var aBool = $('#foo').prop('checked');
Usually, no. Chaining method calls like that is usually simpler, more elegant, and easier to read. However, there are a few cases when it's better to use a variable.
If you use a method (or chain of methods) a lot of times, you can use a variable if it makes the code cleaner.
If the method takes a long time to process, it's better to cache the result. For example, if you have some method called calculateResults(), and it pulls data from a database, that takes some time. If the data doesn't change, you'll be incurring that cost for each call to the method. Better to store it in a variable and reuse it.
If the method has side effects, you should be careful about calling it more than once. Those side-effects will be inflicted each time you call it. Again, as an example, if you have a function like nextItem() that advances to the next item and returns it (a la Java iterators), then calling it more than intended will actually change the result. In this case, you have no choice but store the result, since calling it more than once will produce incorrect behavior.
Otherwise, chain away!
I see this used a lot and I was told putting the function reference between quotes was bad because setTimeout/setInterval evals the reference. What is the actual difference between these two such that one is used over the other and why do I see this used so frequently even though it should be common knowledge that this one way is bad?
People may not realize they can use the unquoted form.
The name referenced in the string may not yet be defined.
The quoted form gives you delayed execution:
setTimeout("myFunction(1, 'hello')", 100)
is easier to understand than:
setTimeout(function () { myFunction(1, 'hello') }, 100)
and this doesn't do what the author wants:
setTimeout(myFunction(1, 'hello'), 100)
There are two main differences between these two forms:
setTimeout("myFunc()", 100);
and
setTimeout(myFunc, 100);
The first is less efficient and it evaluates the function in the global scope so you can't pass it a local function or any function that isn't global.
In a look at the efficiency argument, if you wanted to call a function you had in your code would you write:
x = myFunc();
or would you write:
x = eval("myFunc()");
Of course, you'd write the first one because:
That's how you normally write javascript
The function reference can be resolved once in the first pass of the interpreter rather than each time it executes
Minifiers/optimizers can rename your symbol with the first, but not the second.
You can call local functions with the first one, but the second requires a global function
eval() is a fairly heavyweight thing that should be used only when there is no other better way to do it.
FYI, this jsPerf comparison indicates that the eval() version is 96% slower. The performance might not matter in some circumstances, but you can get the idea how much less efficient it is.
I bet it also prevents memory leaks.
Doesn't leak X:
var x = $("loading");
setTimeout("createTree(1);", 0);
Leak's X:
var x = $("loading");
setTimeout(function(){createTree(1);}, 0);
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.