Suppose I have to write a javascript function:
function(){
var a=1;
var sum=1;
for(var i=0;i<6;i++){
sum=sum+a+1;
}
console.log(sum);
}
Someone recommended me to write this function like this:
function () {
var a = 1;
var sum = 1;
for (var i = 0; i < 6; i++) {
var sum = sum + a +1;
}
console.log(sum);
}
With more blank space, I know this rule, but I don't how it works, or what can I benefit from it?
It is a matter of opinion what good style is, but in a general sense picking some style and consistently following it throughout your code makes it easier to read (both for other people and for you when you come back to it later).
In my experience most people find code easier to read with the extra spaces as shown in your second example.
I don't like putting a space between function and (). Or, where there is a function name I don't put a space between the name and the parentheses: function someName().
Note also that with modern code editors that have syntax highlighting (like Stack Overflow does) it is much easier than it used to be to read code that doesn't have spaces. Compare the following two:
for(var i=0;i<6;i++)
for(var i=0;i<6;i++)
Reading and editing the latter, all in black and white, really annoys me, but I don't mind the coloured version anywhere near as much. I still prefer it with the extra spaces though.
I'd make some other changes in your function:
function() {
var a = 1,
sum = 1,
i;
for(i = 0; i < 6; i++){
sum += a + 1;
}
console.log(sum);
}
The benefit of coding style is enhanced readability. It does not really matter what style you decide to stick to, as long as you DO stick with a uniform style, and can agree with your coworkers on its readability, which is not always easy.
These coding conventions are for humans, they increase readability. Suppose I have written an expression like this:
x=(a*b/2)+m-n+c*(d/e);
It looks clumsy and difficult to read. It would have been easier to understand if we had used spaces around operators like this:
x = (a * b / 2) + m - n + c * (d / e);
Again using blank line increases readability by denoting sections. For example:
function foo() {
var a;
var b;
// a blank line here to specify the end of variable declarations
if (some_cond) {
} else if (another_cond) {
}
// another blank line to specify end of some logic
//more codes here;
}
If you do not follow these guidelines and all team members do not agree in some convention then it will be very difficult to maintain a big project for long time.
Finally note that, the conventions are not for compilers, they are for humans. That's why it is called coding guidelines, not language syntax.
May be you should read more about javascript closure, and you can follow "Google Javascript Style Guide".
Following some uniform style guidelines when coding makes code easier to read and helps you writing beautiful code, and others understanding (and loving!) your code.
For sure there are loads of resources on the net (just by googling for a while you get some javascript guides or guidelines), but this one is quite easy, simple and complete:
http://javascript.crockford.com/code.html
It's not a rule. It's just coding convention style. You don't need to follow if you don't want. But this style can make your code more readable, easier to maintain, and cleaner. To me, I prefer to have space rather than narrow letters. Again, it's not a rule.
Coding style is always very personal; one person likes condensed code so that they can see as much as possible on one screen, another needs the opening and closing braces on a separate line, etc.
When only coding for yourself, you should choose whatever is best for you. But when you start working in teams and others have to maintain your code and visa versa, it becomes important to agree on one coding style ... and this can be hard.
I've sat in coding style discussions and they're very uncomfortable, because you're giving up some of your personal preferences albeit for the greater good. After a brief moment of discomfort you will get used to it ;-)
The second version isn't equivalent to the first, as it declares an inner 'sum' variable, unless Javascript doesn't do what it says on the tin with that.
The extra blank lines don't contribute anything much IMHO, but I probably wouldn't die in a ditch about them. However an equally valid concern is download speed, which is made worse by the suggestion.
Related
I have some code that uses JavaScript’s Math functions quite a lot, to the point that I’d much rather be writing things like exp(cos(PI/2)) instead of Math.exp(Math.cos(Math.PI/2)), which gets ugly and unreadable fast. Even an alias like m. would be clutter. To that extent, I need a simple bit of header code to enumerate over Math and pull its entries into the current scope.
Good news is, standing on the shoulders of Stack Overflow giants, I’ve built an elegant solution to share with the world!! 🥳 Here it is:
// Import all Math numbers and functions to the current (global) scope.
for (let name of Object.getOwnPropertyNames(Math))
globalThis[name] = Math[name]
console.log( exp(cos(PI/2)) ) // = 1
Codepen
I’m very happy with it, posting it here to give back to the community and to see if anyone has improvements! 💞 It truly just feels so much cleaner now, like how it should’ve always been. Math functions deserve to be global!
Posted above!
// Import all Math numbers and functions to the current (global) scope.
for (let name of Object.getOwnPropertyNames(Math))
globalThis[name] = Math[name]
console.log( exp(cos(PI/2)) ) // = 1
Codepen
I was playing around so I ran into a JS shorthands. I know they, of course, do not change code however do they lower loading time since there is less data?
Testing codes such as one below in Chrome DOM inspector did not give me an answer (probably because they are one-line codes so it does not make any difference).
if (x == 0) {x=1} else {x=2}
x == 0 ? x = 1 : x = 2;
If your goal is to optimize the speed with which your page loads by minimizing the size of your JS payload, there are lots of tools that will automatically rebuild your files into a single bundle that is compressed (i.e., all unnecessary whitespace removed, variables/functions renamed to shorter lengths, etc.). When it comes to writing code, you should always value readability first.
Write code that other people can easily understand. Then, when you're ready to deploy, look into a tool like UglifyJS2, which will enable you to take code like this:
function square(numToSquare) {
var squareProduct = numToSquare * numToSquare;
return squareProduct;
}
square(15);
..and turn it into this:
function square(r){return r*r}square(15);
The less characters and whitespace in a file, the lower the download size of said scripts is.
Readability is also a matter of utmost importance though, and ternary operators can be confusing in certain scenarios.
I would recommend that for those cases where you expect your codebase to increase to a certain extend over time, you stick to more readable constructs and use a minification/uglification process to lower file size.
I am working on a project that has a testimony slideshow for my website. I am using php and mysql for the database. I want to use pure javascript to display the name and comment from the database. I already have the names and comments pulled from the database and stored into a javascript array. I have made it so the text displays by using setInterval and rand() to change the variable, but it does not rotate to the next image.This is my script right now.
function showComment(number) {
document.write('<p>');
document.write(unescapeHtml(js_comment[number]));
document.write('</p>');
document.write('<p>');
document.write(unescapeHtml(js_name[number]));
document.write('</p>');
}
setInterval(showComment(Math.floor(Math.random()*num_results), 2431);
js_comment[] and js_name[] are the variables with the name and comment from php num_results is the number of comments
jsfiddle for it so far jsfiddle.net/4nq2c0xb/
You would likely want to use a container and textContent / innerText, e.g.:
<p id="comment"></p>
<h3 id="name"></h3>
And then first get the elements:
var comment = document.getElementById('comment');
var name = document.getElementById('name');
And in the interval function:
comment.textContent = js_comment[number];
name.textContent = js_name[number];
https://developer.mozilla.org/en-US/docs/Web/API/Node.textContent#Browser_compatibility
http://clubajax.org/plain-text-vs-innertext-vs-textcontent/
Short update:
Not directly related to question, but some thoughts in regard to comments etc. I also register you might be in a beginner phase where basic concepts might be more important; but add it anyhow.
Note that when you have some code of some size you can also use
Code Review SE
to get input on your code. Hints and help on good and bad, how to refactor etc.
Variable scope:
If new to JavaScript this might be a bit out of scope of how your compendium are set up and where you are, but mention it as it is a rather important topic.
The first thing of concern when looking at your code is variable scope. To put it short: avoid global variables. That is variables that are accessible and modifiable from anywhere. This is highly frowned upon when it comes to production code. In short: It quickly becomes a nightmare to keep track of variables in global scope. It is prone for very ugly bugs etc. Maintaining such code, not the least for others, or your self after say 6 months, a year or what ever, also quickly makes it hard to read and so on.
How to avoid global variables in JavaScript?
In this regard there is also the need to always define variables. Not that you have not done it, but still. Personally I usually define variables in top of functions (quite a few people disagree with this, but my pref.). This way I know what variables are used, it is quick to control that it has been defined, it is a good place for a overview with comments etc.
What is the scope of variables in JavaScript?
All to note. It is important to know where variables exists. E.g. changing a global variable affects it in all functions using that variable.
Write short concise functions:
I follow the rule of thumb: “let a function do one thing, and do it well.” If a function do too much it often gets hard to maintain, it is prone for bugs, the re-usability is quickly gone etc.
Of course, sometimes I stray from this, especially if it is short example code or some quick and dirty temporary solution, testing some concept or the like; but, I have more then once also regretted this by having to use lot of time refactoring the code afterwards.
It is at least something to keep in mind.
Keep functions short.
Be very careful not to have deep nesting etc., bad:
if () {
if () {
for () {
...
Use strict mode:
What does “use strict” do in JavaScript, and what is the reasoning behind it?
Wrap your code in a strict scope:
(function(){
"use strict";
function foo() {
}
function bar() {
}
})();
Some of the advantages are described in linked answer.
Use code analysis tools:
Should I use JSLint or JSHint JavaScript validation?
This can be somewhat too much for some newcomers as it seems all the code is bad all the time ;). It takes some experience to get used to and if one do not know the language well, it can, I guess, often be hard to understand why some things are considered bad. But; it is a good way of developing good habits. Personally I have it incorporated into my editor of choice, Vim, and as such every time I save, which I do often, I get feedback from the tool on things I might have overlooked etc. One have the possibility to tweak it. There are some of the hints it gives that I disagree with – but it is all over a good way of checking your code.
As a start, if you want to test it, you can copy paste your code into online tools:
JSLint
JSHint
to get a feel of how it works.
Design patterns:
This might be somewhat overwhelming, as there are so many ways (and opinions), but skimming the information and getting a feel on it might be good.
Yes, OO programming is powerful, but as a personal opinion I try not to force JS to be like Java and the like – simulate Classes etc. JS has it's own possibilities, features etc. and when projects get some size the question comes down to design patterns. Sometimes one will encounter an existing code base where one use Class like approach, and then one usually does not have any choice.
You might find this useful. If you do not read it word for word you might find it clarify some of the concept of it:
JavaScript Programming Patterns – Though I strongly disagree with the authors depiction of The Old-School Way; at least in my experience both namespace, re-usability etc. was a concern back then as well. Not for everyone, but not that dark as described.
Learning JavaScript Design Patterns – Might be somewhat big, but still.
Etc. Search the web for “JavaScript design patterns” and the like.
Here's what I got http://jsfiddle.net/xuxcwcsd/5/:
HTML -
<div id="container">
<h1>Testimonials</h1>
<div id="comment"></div>
</div>
CSS -
#container {
border: 2px solid blue;
padding: 3px 10px;
margin-bottom: 20px;
}
h1 {
color: red;
}
p {
text-align: center;
margin-left: 20px;
}
h3 {
color: blue;
text-align: right;
margin-right: 40px;
}
JavaScript -
//create and fill the array
var commt = [ ];
var name = [ ];
var i = 0;
commt[0] = 'comment 1';
commt[1] = 'comment 2';
commt[2] = 'comment 3';
commt[3] = 'comment 4';
name[0] = 'name 1';
name[1] = 'name 2';
name[2] = 'name 3';
name[3] = 'name 4';
//shows how many comments there are
var maxComments = 4;
//get empty elements
var comment = document.getElementById('comment');
//this section will create the inital comment shown
//creates a random number
var number = Math.floor(Math.random() * 4);
//adds the HTML to div with window.onload
window.onload = comment.innerHTML = "<p>" + commt[number] + "</p>" +
"<h3 class='commentSliderH3'>" + name[number] + "</h3>";
//This rotates the comments
setInterval(function () { //same content as above
var number = Math.floor(Math.random() * maxComments);
comment.innerHTML = "<p>" + commt[number] + "</p>" +
"<h3 class='commentSliderH3'>" + name[number] + "</h3>";
}, 1931); // Runs the function every 9031ms
Is it a bad habit to write reverse loops as:
for (i = N; i--;)
in order to access (N-1) to 0
If so, why? jsLint certainly doesn't like it.
There's no technical reason that this won't work. However, it clearly has readability issues since someone had an immediate "well that won't work!" reaction.
This is the kind of issue that the jQuery team struggles with – whether to use novel constructs that save bytes at the expense of clarity and maintainability. It really comes down to whether it's worth 1 or 3 bytes of savings:
for(var i=9;i--;)
var i=9;while(i--)
for(var i=9;i>0;i--)
In this case, probably not.
It is less readable, without your explanation it would take me few seconds to understand what the loop does. Why not simply:
while(i-- > 0)
?
Did you consider readability? You may very well understand it yourself, but other developers might get confused since the parts of the for "idiom" are usually named as:
for ([initialization]; [condition]; [final-expression])
While the condition can technically be any expression, your version does not conform to this idiom, since the "condition" part you use does more than just defining a condition - it sneakily decrements i as well.
"Is it a bad habit to write reverse loops as:"
for (i = N; i--;)
That's a matter of opinion, but it's effectively a reverse while with initialization, so in my opinion it's not a "bad habit". It's just a coding style.
The specification makes the parts of a for optional to give the developer that flexibility.
"jsLint certainly doesn't like it."
Who cares. You're not bound to follow the opinions of jsLint.
The answers would be very subjective I guess. I don't think it is a bad habit but I do find it aesthetically unpleasing. This can be expressed more elegantly as:
for (i = N - 1; i >= 0; i--) {
// do something here.
}
// And if it is really important that i should be 0 here
// as it is in your original code.
i = 0
This code is easier on our brain while browsing a lot of code that happens to contain this.
Yes. There is a good reason. Readability.
As I'm sure most of the JavaScripters out there are aware, there's a new, Christmas-themed js1k. I'm planning on entering this time, but I have no experience producing such minified code. Does anyone know any good resources for this kind of thing?
Google Closure Compiler is a good javascript minifier.
There is a good online tool for quick use, or you can download the tool and run it as part of a web site build process.
Edit: Added a non-exhaustive list of tricks that you can use to minify JavaScript extremely, before using a minifier:
Shorten long variable names
Use shortened references to built in variables like d=document;w=window.
Set Interval
The setInterval function can take either a function or a string. Pass in a string to reduce the number of characters used: setInterval('a--;b++',10). Note that passing in a string forces an eval invokation so it will be slower than passing in a function.
Reduce Mathematical Calculations
Example a=b+b+b can be reduced to a=3*b.
Use Scientific Notation
10000 can be expressed in scientific notation as 1E4 saving 2 bytes.
Drop leading Zeroes
0.2 = .2 saves a byte
Ternery Operator
if (a > b) {
result = x;
}
else {
result = y;
}
can be expressed as result=a>b?x:y
Drop Braces
Braces are only required for blocks of more than one statement.
Operator Precedence
Rely on operator precedence rather than adding unneeded brackets which aid code readability.
Shorten Variable Assignment
Rather than function x(){a=1,b=2;...}() pass values into the function, function x(a,b){...}(1,2)
Think outside the box
Don't automatically reach for standard ways of doing things. Rather than using d.getElementById('p') to get a reference to a DOM element, could you use b.children[4] where d=document;b=body.
Original source for above list of tricks:
http://thingsinjars.com/post/293/the-quest-for-extreme-javascript-minification/
Spolto is right.
Any code minifier won't do the trick alone. You need to first optimize your code and then make some dirty manual tweaks.
In addition to Spolto's list of tricks I want to encourage the use of logical operators instead of the classical if else syntax. ex:
The following code
if(condition){
exp1;
}else{
exp2;
}
is somewhat equivalent to
condition&&exp1||exp2;
Another thing to consider might be multiple variable declaration :
var a = 1;var b = 2;var c = 1;
can be rewritten as :
var a=c=1,b=2;
Spolto is also right about the braces. You should drop them. But in addition, you should know that they can be dropped even for blocks of more expressions by writing the expressions delimited by a comma(with a leading ; of course) :
if(condition){
exp1;
exp2;
exp3;
}else{
exp4;
exp5;
}
Can be rewritten as :
if(condition)exp1,exp2,exp3;
else exp4,exp5;
Although it's not much (it saves you only 1 character/block for those who are counting), it might come in handy. (By the way, the latest Google Closure Compiler does this trick too).
Another trick worth mentioning is the controversial with functionality.
If you care more about the size, then you should use this because it might reduce code size.
For example, let's consider this object method:
object.method=function(){
this.a=this.b;
this.c++;
this.d(this.e);
}
This can be rewritten as :
object.method=function(){
with(this){
a=b;
c++;
d(e);
}
}
which is in most cases signifficantly smaller.
Something that most code packers & minifiers do not do is replacing large repeating tokens in the code with smaller ones. This is a nasty hack that also requires the use of eval, but since we're in it for the space, I don't think that should be a problem. Let's say you have this code :
a=function(){/*code here*/};
b=function(){/*code here*/};
c=function(){/*code here*/};
/*...*/
z=function(){/*code here*/};
This code has many "function" keywords repeating. What if you could replace them with a single(unused) character and then evaluate the code?
Here's how I would do it :
eval('a=F(){/*codehere*/};b=F(){/*codehere*/};c=F(){/*codehere*/};/*...*/z=F(){/*codehere*/};'.replace(/function/g,'F'));
Of course the replaced token(s) can be anything since our code is reduced to an evaluated string (ex: we could've replaced =function(){ with F, thus saving even more characters).
Note that this technique must be used with caution, because you can easily screw up your code with multiple text replacements; moreover, you should use it only in cases where it helps (ex: if you only have 4 function tokens, replacing them with a smaller token and then evaluating the code might actually increase the code length :
var a = "eval(''.replace(/function/g,'F'))".length,
b = ('function'.length-'F'.length)*4;
alert("you should" + (a<b?"":" NOT") + " use this technique!");
In the following link you'll find surprisingly good tricks to minify js code for this competition:
http://www.claudiocc.com/javascript-golfing/
One example: (extracted from section Short-circuit operators):
if (p) p=q; // before
p=p&&q; // after
if (!p) p=q; // before
p=p||q; // after
Or the more essoteric Canvas context hash trick:
// before
a.beginPath
a.fillRect
a.lineTo
a.stroke
a.transform
a.arc
// after
for(Z in a)a[Z[0]+(Z[6]||Z[2])]=a[Z];
a.ba
a.fc
a.ln
a.sr
a.to
a.ac
And here is another resource link with amazingly good tricks: https://github.com/jed/140bytes/wiki/Byte-saving-techniques
First off all, just throwing your code into a minifier won't help you that much. You need to have the extreme small file size in mind when you write the code. So in part, you need to learn all the tricks yourself.
Also, when it comes to minifiers, UglifyJS is the new shooting star here, its output is smaller than GCC's and it's way faster too. And since it's written in pure JavaScript it should be trivial for you to find out what all the tricks are that it applies.
But in the end it all comes down to whether you can find an intelligent, small solution for something that's awsome.
Also:
Dean Edwards Packer
http://dean.edwards.name/packer/
Uglify JS
http://marijnhaverbeke.nl/uglifyjs
A friend wrote jscrush packer for js1k.
Keep in mind to keep as much code self-similar as possible.
My workflow for extreme packing is: closure (pretty print) -> hand optimizations, function similarity, other code similarity -> closure (whitespace only) -> jscrush.
This packs away about 25% of the data.
There's also packify, but I haven't tested that myself.
This is the only online version of #cowboy's packer script:
http://iwantaneff.in/packer/
Very handy for packing / minifying JS