JavaScript Essentials

https://www.dofactory.com/javascript/essentials

JavaScript Essentials

JavaScript is case-sensitive

JavaScript is case-sensitive. Keywords such as for and function, must be in their proper case (i.e. lowercase) and not For and Function, or FOR and FUNCTION. Similarly, totalamount, totalAmount, TotalAmount, and totalAMOUNT are 4 distinct variable names in JavaScript.

When using JavaScript on the browser it is important to realize that HTML is not case-sensitive which may lead to some confusion. For instance, event attribute names can be typed in any case in HTML, so both onclick and onClick work. In JavaScript, it is typically all lowercase.

<!-- the same --><a href="index.html" onclick="handler();" /><a href="index.html" onClick="handler();" />

Coding conventions and naming standards are important for JavaScript programmers. Most use camelCase for their variable and function names, such as, savingsAccount and computeProfits. Constructor functions are by convention written in PascalCase, such as, Employee and LegalDocument. Iterator variables are commonly single character lower case letters, such as i, j, and k, as in for (var i = 0; i < 10; i++) {…}.

A JavaScript project should use a consistent set of coding standards and naming conventions. This is particular important when the project is a team effort. Ideally, when exploring a project's code base, it should feel as if it were written by a single developer. This consistency will ensure that all parts of the program are easy to learn and easy to support, irrespective who originally wrote it.

To get your JavaScript project off to a good start we have included a list of modern naming conventions and coding standards in our JavaScript + jQuery Design Pattern Framework. To learn more click here. Previous Next

Debugging JavaScript

Developers commonly use alert to print messages in a dialog box to help determine what is wrong in a certain part of their code. The statement below will show the total amount after the program has calculated the value.

var totalAmount = quantity * unitPrice;   // some computationalert("Amount is $", totalAmount);        // => Amount is $977.50

Clearly, alert as a debugging tool is very limited. First, it is only capable of displaying a simple string message and does not allow you to inspect more complex variables, such as arrays and objects. Secondly, it creates a modal window which prevents further interaction with the browser until the pop-up window is dismissed. This is particularly problematic when alert is placed in loops because you may end up having to close a large number of message boxes. Finally, there is a real risk that these messages are seen by end-users when the developer forgets to remove the alert before deployment.

Fortunately, more advanced debugging tools are now available. As an example we will review Firebug next.

JavaScript debugging with Firebug

The Firebug extension for Firefox offers a solid JavaScript debugging experience. To use it you must first install the free Firebug extension. Then select Tools -> Firebug->Open Firebug (or hit F12) to get started.

Consider the following code:

var totalAmount = quantity * unitPrice;console.log(totalAmount);                   // => 1740.22

The console.log writes the value to the Firebug's console panel which can then be viewed later without interrupting the program flow. Even if you forget to remove the console.log statement the output is generally not visible to end-users. Furthermore, more complex types like arrays and objects are easily debugged and inspected in Firebug. Consider this array for vehicles:

var vehicles = [    {"type": "cars", "items": ["SUV", "Pickup", "Sedan"]},    {"type": "trucks", "items": ["Trailer", "Dump Truck", "Tanker"]}];

Using alert(vehicles) would only tell you what type of variable vehicles is, which is usually not what you want. On the other hand, the console panel lets you explore the entire contents of the vehicles variable. You can drill down by clicking on items and easily explore its values.

[Object { type="cars", items=[3],  Object { type="trucks", items=[3] } } ]

Firebug offers a rich debugging environment. You can set breakpoints which pause execution when the program reaches a particular line. You can set conditional breakpoints which suspend the execution when a particular expression is true. You can step through the code line by line and follow its execution in great detail. You can jump directly to a particular line of the script by simply typing the line number. And, when an error occurs, you can break into the debugger automatically.

When paused, you can inspect the values of all variables, objects, and even complex expressions. To determine where a particular call originated in the stack, you can inspect the call stack which is represented as a strip of buttons in the toolbar, each with the name of a function on the stack. Click on any of these buttons and you will be taken to the function and the calling line where you can inspect the values of the function's local variables.

The console object is offered by most browsers, but note that it is part of the host environment and not of the language itself. IE 8 and higher offer similar functionality as part of the Developer Tools; Chrome and Safari offer it as part of Web Inspector.

Writing comments in JavaScript

In JavaScript a single line comment begins with a double slash //. All text to the right of it will be ignored by the compiler. This type of comment is typically used for quick notes about complex code or to temporarily remove a line of code (this is called 'commenting out').

var totalAmount;   // holds the quantity multiplied by unitPrice

A multi-line comment, also called block comment, begins with /* and ends with */. These are typically used to write comments that span multiple lines and also to comment out large blocks of code, possibly for debugging purposes.

/* Indicates the user role.   The application has 3 predefined roles:   1) Admin, 2) Guest, and 3) User (registered user)*/var userRole;

When using multi-line comments you need to be careful not to include the character combination */ as used in regular expressions. In the following two examples, syntax errors will be reported (notice that even our syntax highlighter is confused...).

/* Return the position of the match in the string     'JavaScript' which contains the string 'Jav'    followed by the character 'a' any number of times.   var position = 'JavaScript'.search(/Java*/g);*//* Type comments were added   var IsSystemUser /*:Boolean*/ =  false;   var userCount /*:int*/ =  1;*/

Because of the above risks, it is generally recommended you use // comments whenever possible.

Using JSLint &JSHint

JavaScript is a weakly typed language without a compiler to check for syntax errors before runtime. Because of this, the risk of bugs slipping through the cracks is fairly high. This is where JSLint comes to the rescue. JSLint is a code quality tool that scans and analyzes your JavaScript code, checks the syntax, checks for potential problems, bad practices, incorrect usage of the language, and reports problems and their locations in the code file. JSLint introduces some level of discipline that is otherwise lacking in JavaScript programming.

Most browsers will let you get away with code like this:

function x() {  arr = new Array()  arr['num1'] = "012"  no = parseInt( arr['num1'] )  if(nov == 12)     for (i=0;i<arr.length;i++) if(arr[i] != null) return true  return false};

However, when you pass this code through JSLint it will report more than a dozen problems! See how many you can find without viewing the JSLint report.

JSLint catches several categories of bugs before they get to the browser. For instance, having a comma after the last element in an array is invalid in JavaScript, but most browsers ignore it and don't complain. However, IE reports an error message "Unexpected identifier, string or number". JSLint helps to detect this kind of syntax errors.

JSLint requires the code to be compliant with strict mode; all variables and functions need to be declared before they are used or invoked. It favors the use of strict equality operators, that is === and !==, over these == and != which do not perform type conversion. JSLint discourages the use of eval(), with, ++, --, void, and bitwise operators. It also expects constructor function names to start with an uppercase letter.

To prevent unintended fall-through in a switch statement, JSLint requires that the statement before the next case is either, a break, a return, or a throw statement. It expects new objects to be created with {} rather than new Object. It ensures that all JSON data structures are well formed. It also looks for unreachable code, improperly escaped characters in regular expressions, and UTF characters that are considered unsafe.

JSLint recommends using a global declaration comment to let it identify the names of all your global variables. This helps JSLint find variable declarations you misspelled or forgot to prefix with a var. A declaration comment must appear before the variables specified are used, for example:

/* global totalCount, totalSales */...var totalCount = 0;var totalSales = 0;

JSLint is highly configurable and its options are specified on top of the script as a sequence of name-value pairs in your code, where the name is a JSLint option and its value is either true or false. The default of all values is false. Here is an example:

/* jslint cap:true, debug:true, passfail:true,    evil:false, plusplus:false */

The first three options: cap, debug, and passfail are all set to true, indicating that uppercase HTML is allowed, debugger statements are allowed, and that the scan should stop on the first error it detects. The evil (not a typo!) and plusplus options are set to false indicating that the use of eval() and ++ and -- operators is not allowed.

JSLint even examines the HTML trying to locate problems that are known to frequently occur with JavaScript. It expects all HTML tag names to be lowercase and be nested correctly. Also, it ensures that you use < for a < literal.

A recent fork of JSLint called JSHint is becoming rather popular. Among other things, it is far more configurable than JSLint so that it can handle different coding styles. Whichever you use, be sure that you 'lint' or 'hint' your JavaScript programs.

JavaScript security

In this section we will review JavaScript's eval() function and its potential security pitfalls.

The built-in eval() function accepts a string as an argument. If the argument is a valid JavaScript expression, eval() evaluates the expression and returns its value. For example, eval("6+4") returns 10. If the argument is one or more JavaScript statements, or an entire program, eval() will happily execute them all and returns the value of the last statement.

While eval() is a powerful way to dynamically execute JavaScript code, it is also dangerous and has security implications associated with it. A hacker could easily inject rogue code that might compromise the security of your application. This is known as code injection.

In reality, when the code is known in advance, there really no need to dynamically execute code. It is only needed when you dynamically generate code at runtime. For instance, you have an object, called car, and want to access a property on it and you don't know the property's name until runtime.

var car = {};var property = "color";eval("car." + property + " = 'white';");  alert(car[property]);                     // => white

Run

Although it works, there are several problems with this code. First, it is harder to read and maintain. Second, execution of this type of code is considerably slower because JavaScript will have to go back into the compiler/interpreted mode in the midst of runtime just to execute this trivial statement. Third, it hinders the ability of JSLint to identify problems to a great extent. Finally, and most importantly, a hacker may be able to inject code with consequences that you never anticipated.

Instead of using literal dot-names to access the dynamic properties, make use of the square bracket notation which is much better and simpler way to achieve the same result.

var car = {};var property = "color";car[property] = 'white';alert(car[property]);       // => white

Run

With all these potential pitfalls and security risks it is best to avoid the use of eval() altogether.

Last updated

Navigation

Lionel

@Copyright 2023