MIS 370 Client Side Programming
Style and Best Practices Guide
Introduction: Why Code Style Matters
It is absolutely possible to write code that works flawlessly from the user's perspective, but is nearly impossible to read and that does not follow best practices for the language. But if it works, why should it matter?
Following suggested styles and practices will
Following suggested styles and practices will
- Make it easier for someone else to read your code.
This may not matter much if you're not planning to share it, but within a classroom or workplace environment, you will always be under the assumption that your code will be read by other people. If you want help debugging code, or just want to show off a clever function, you'll need to ensure that they can understand what they're looking at. Keep in mind that your JavaScript code is visible to anyone that views your page, simply by viewing its source. Your potential employer is likely to take a look at your online portfolio to evaluate your coding practices. Assume your future boss will be seeing your code. - Make it easier to find your errors.
Syntax errors are much easier to spot when your code is well organized and aligned. - Ensure your code is secure.
Code should never leave you or your users as risk. While vulnerabilities in JavaScript are rare, they do exist. They are also easy to avoid. - Improve your grade.
This certainly only applies to this course, but a lack of attention to proper style will result in a lower assignment grade, even if your code is functional and error free.
Comments
- Feel free to be generous with comments, but avoid redundancy. Well written code is usually easy to read and understand without comments explaining each step. See Donald Knuth's Literate Programming, specifically the introduction, for a good goal to keep in mind.
- Leave comments explaining why your code is written the way it is, not how it works. You will not be required to include comments simply for the sake of having them.
- Remember that every character, including whitespace and non-alphanumeric characters, cost 1 byte in your file size. This is not much, but it adds up. Avoid overly elaborate comment boxes.
/**************************************************/ /**************************************************/ /****** ******/ /****** This sure gets your attention!!!!! ******/ /****** ******/ /**************************************************/ /**************************************************/ // But this works too, and isn't 364 bytes
Variables
- Variable names should be descriptive, preventing the need for a series of comments explaining what each variable is for. Avoid single letters and _ for variables that appear several times throughout your code. The code below would require comments, as it's very difficult to guess what it's doing without them:
var a = function(m,n) { // function to return area of rectangle with width m and height n return m*n; } var x = 9; // x is the width of a rectangle var y = 21; // y is the height of a rectangle a(x,y);
The exact same code is below, but with variable names that give us some sense of what the code is for:var areaOfRect = function( m,n ) { return m*n; } var width = 9; var height = 21; areaOfRect( width, height );
- Use camel (eachNewWordCapitalized) or snake case (separated_with_underscores) as you prefer, or even a mix of both. There may be an argument for using snake space with regards to accessibility and audio readers, but you will not be held to this standard within class.
- Make sure your variable names are legal. JavaScript keywords (including some words that are reserved for definition in later version of JavaScript) are obviously bad choices: you cannot define a variable called 'for' or 'array'.
- All variable names must begin with a letter, _, or $. Names cannot begin with numbers.
- While JavaScript is case sensitive, avoid using names that would be similar if cases are ignored. It would be very tedious to find an error in code featuring variables called name, Name, NAME, and _name, for instance.
Indentation and Whitespace
- Whitespace is ignored by JavaScript (unlike languages like Python), so your use of it depends entirely on style preferences, not function. While whitespace should be used efficiently, it can be one of the easiest ways to make good looking and easy to debug code.
- Use spaces to separate tokens, and place code blocks on their own lines.
- Brace style is largely up to you. Any of the styles shown here except LISP are fine, just be consistent. I personally tend to use the K&R style, specifically the Stroustrup variant. I find this style makes it easy to detect missing braces, see exactly where each block begins and ends, and does not look cluttered.
- Code blocks should be indented to ease reading and clarify the logic used. Spaces (at least 2) or tabs are fine, but be consistent. I usually use tabs. Always surround blocks with braces, even with one line blocks (yes, they can sometimes be left off, but this is terrible practice).
- A sample of what NOT to do:
var test = function(x) {if (typeof x==='number') {if (x>0){ for(var i=0;i < x;i++) {x+=i;}}}}
The code below is identical, except for the addition of whitespace.var test = function ( x ) { if ( typeof x === 'number' ) { if ( x > 0 ) { for ( var i = 0; i < x; i++ ) { x += i; } } } }
Semicolons
Semicolons are used to end statements in JavaScript. Most interpreters will interpret a new line as the end of a statement as well, which means we can almost always get away with leaving the semicolons out. While we may not see many examples in class where it makes a difference, you will be expected to include semicolons at the end of each statement in your code. One major advantage of this practice is making it easy to "minify" your code - removing all extraneous whitespace, resulting in a much smaller file that is far more efficient for machines to read (but nearly impossible for humans).
String Quotes
Surround quotes with either double or single string. I tend to use single for things like element IDs that rarely involve any other punctuation, and double for strings that may be displayed to the user, as apostrophes are tolerated within double quotes.
Operators
- When testing, use the logical operators && and || rather than bitwise operators & or |.
- Avoid forcing type coercion. Unless you have a specific reason to use == for testing equivalence, it is generally recommended to use === instead. Similarly, use !== rather than !=. See here for an old but useful discussion on this topic.
- Use ! for negation, not ~.
New Objects
The
new
method for array or object declaration should be avoided. There's not much of an issue with it, it's simply considered an obsolete way of creating objects.
// Use this to define an empty array: var myArray = []; // rather than new: var myArray = new Array();
Functions
Functions should be assigned to identifiers using either expression style or definition style. There may be times when only one style will work correctly due to scoping issues, so choose wisely.
// expression style: var giveMeAnA = function () { return 'A'; } // definition style: function giveMeAnA() { return 'A'; }A good, though outdated, discussion on the topic can be found here.
Shorthand Notation
Feel free to use shorthand notation if you know it, though you will not be required to. Be aware that shorthand notation does make for cleaner code, but may be more difficult to read. We'll begin using shorthand notation later in the semester. If you sometimes have trouble following the logic of a code block, you may want to avoid shorthand notation for now, as it obscures what exactly the code achieves.
// This code: if ( x % 2 === 0 ) { var message = "x is even"; } else { var message = "x is odd"; } // can also be written using shorthand notation like this: var message = ( x % 2 === 0 ) ? "x is even" : "x is odd";
eval()
Unless specifically directed within an assignment, NEVER use
eval()
. When used haphazardly, eval()
could leave you or a viewer of your page open to security threats. While it can be used safely, avoid it for this course.Debugging Functions
Functions intended primarily to be used for debugging purposes, like
console.log()
, should be removed before your code is considered complete. Clear exceptions include assignments that require console output, but unless such functions are mentioned in the assignment, please remove them before submitting your work.
Efficient Loops
You can have a significantly increase in speed through careful variable definition. For instance, the loop below works as intended, printing the contents of the array to a DOM element with an ID of 'output'.
var myArray = [ 1, 2, 3 ]; for ( var i = 0; i < myArray.length; i++ ) { document.getElementById('output').innerHTML += i; }There are two improvements to make here, however. With each loop, we're requiring a calculation of the length of the array. With only 3 items, that's not such a big deal, but larger arrays can cause a delay. We're also forcing a search for the required DOM element in each loop. We can fix both of these issues by declaring a variable for each outside the loop. There are additional lines of code, but it will be much more efficient:
var myArray = [ 1, 2, 3 ]; var arrayLength = myArray.length; var outputElement = document.getElementById('output'); for ( var i = 0; i < arrayLength; i++ ) { outputElement.innerHTML += i; }
A Word on Autofix/Autoclean Editors
Many editors come with the ability to "autofix" your code. This might include adding or removing whitespace, adding characters like semicolons, or other alterations performed automatically. While these editors may make some improvements to the appearance of your code, please manually check all changes. You are ultimately responsible for the formatting of the code you submit.
JSLint
If you have a linter you're happy with, feel free to continue using it. If not, there is an easy to use, free linter called JSLint that allows you to paste your code and check for any possible issues.
NOTE: JSLint will find errors, and you are not expected to meet it's standard on assignments (other than those outlined above). Do not worry about warnings regarding 'for' or single quote strings, for instance. But it is still a great tool to make sure your code is on the right track and even find errors like missing brackets.
Be aware, according to their own site, "JSLint will hurt your feelings. Side effects may include headache, irritability, dizziness, snarkiness, stomach pain, defensiveness, dry mouth, cleaner code, and a reduced error rate."
NOTE: JSLint will find errors, and you are not expected to meet it's standard on assignments (other than those outlined above). Do not worry about warnings regarding 'for' or single quote strings, for instance. But it is still a great tool to make sure your code is on the right track and even find errors like missing brackets.
Be aware, according to their own site, "JSLint will hurt your feelings. Side effects may include headache, irritability, dizziness, snarkiness, stomach pain, defensiveness, dry mouth, cleaner code, and a reduced error rate."