Hoisting is JavaScript's default behavior of moving declarations to the top.
In JavaScript, a variable can be declared after it has been used.
In other words; a variable can be used before it has been declared.
Example 1 gives the same result as Example 2:
x = 5; // Assign 5 to x
elem = document.getElementById("demo"); // Find an element
elem.innerHTML = x; // Display x in the element
var x; // Declare x
var x; // Declare x
x = 5; // Assign 5 to x
elem = document.getElementById("demo"); // Find an element
elem.innerHTML = x; // Display x in the element
To understand this, you have to understand the term "hoisting".
Hoisting is JavaScript's default behavior of moving all declarations to the top of the current scope (to the top of the current script or the current function).
JavaScript only hoists declarations, not initializations.
Example 1 does not give the same result as Example 2:
var x = 5; // Initialize x
var y = 7; // Initialize y
elem = document.getElementById("demo"); // Find an element
elem.innerHTML = x + " " + y; // Display x and y
var x = 5; // Initialize x
elem = document.getElementById("demo"); // Find an element
elem.innerHTML = x + " " + y; // Display x and y
var y = 7; // Initialize y
Does it make sense that y is undefined in the last example?
This is because only the declaration (var y), not the initialization (=7) is hoisted to the top.
Because of hoisting, y has been declared before it is used, but because initializations are not hoisted, the value of y is undefined.
Example 2 is the same as writing:
var x = 5; // Initialize x
var y; // Declare y
elem = document.getElementById("demo"); // Find an element
elem.innerHTML = x + " " + y; // Display x and y
y = 7; // Assign 7 to y
Hoisting is (to many developers) an unknown or overlooked behavior of JavaScript.
If a developer doesn't understand hoisting, programs may contain bugs (errors).
To avoid bugs, always declare all variables at the beginning of every scope.
Since this is how JavaScript interprets the code, it is always a good rule.
JavaScript in strict mode does not allow variables to be used if they are not declared. |
"use strict"; Defines that JavaScript code should be executed in "strict mode".
The "use strict" directive is new in JavaScript 1.8.5 (ECMAScript version 5).
It is not a statement, but a literal expression, ignored by earlier versions of JavaScript.
The purpose of "use strict" is to indicate that the code should be executed in "strict mode".
With strict mode, you cannot, for example, use undeclared variables.
Strict mode is supported in: |
Strict mode is declared by adding "use strict"; to the beginning of a JavaScript file, or a JavaScript function.
Declared at the beginning of a JavaScript file, it has global scope (all code will execute in strict mode).
Declared inside a function, it has local scope (only the code inside the function is in strict mode).
Global declaration:
"use strict";
function testStrict(){
var x;
x = 3.14; // This does not cause an error.
}
x = 3.14; // This causes an error.
Local declaration:
function testStrict(){
"use strict";
x = 3.14; // This causes an error.
}
x = 3.14; // This does not cause an error.
The syntax, for declaring strict mode, was designed to be compatible with older versions of JavaScript.
Compiling a numeric literal (4 + 5;) or a string literal ("John Doe";) in a JavaScript program has no side effects. It simply compiles to a non existing variable and dies.
So "use strict;" only matters to new compilers that "understand" the meaning of it.
Strict mode makes it easier to write "secure" JavaScript.
Strict mode changes previously accepted "bad syntax" into real errors.
As an example, in normal JavaScript, mistyping a variable name creates a new global variable. In strict mode, this will throw an error, making it impossible to accidentally create a global variable.
In normal JavaScript, a developer will not receive any error feedback assigning values to non-writable properties.
In strict mode, any assignment to a non-writable property, a getter-only property, a non-existing property, a non-existing variable, or a non-existing object, will throw an error.
Using a variable (property or object) without declaring it, is not allowed:
x = 3.14; // This causes an error (if x has not been declared).
Deleting a variable, a function, or an argument, is not allowed.
var testStrict = 3.14;
delete testStrict; // This causes an error.
Defining a property more than once, is not allowed:
var testStrict = {p1:10, p2:15, p1:20}; // This causes an error.
Duplicating a parameter name is not allowed:
function testStrict(param1, param1) {}; // This causes an error.
Octal numeric literals and escape characters are not allowed:
var testStrict = 010; // This causes an error.
var testStrict = \010; // This causes an error.
Writing to a read-only property is not allowed:
var testObj = {};
Object.defineProperty(testObj, "x", {value:0, writable:false});
testObj.x = 3.14; // This causes an error.
Writing to a get-only property is not allowed:
var testObj = {get x() {return 0} };
testObj.x = 3.14; // This causes an error.
Deleting an undeletable property is not allowed:
delete Object.prototype; // This causes an error.
The string "eval" cannot be used as a variable:
var eval = 3.14; // This causes an error.
The string "arguments" cannot be used as a variable:
var arguments = 3.14; // This causes an error.
The with statement is not allowed:
with (Math){x = cos(2)}; // This causes an error.
Future reserved keywords are not allowed. These are:
In function calls like f(), the this value was the global object. In strict mode, it is now undefined.
For security reasons, in strict mode code, eval does not create a new variable in the scope from which it was called.
With strict mode, you cannot, for example, use undeclared variables.
The "use strict" directive is only recognized at the beginning of a script or a function. |
Always use the same coding conventions for all your JavaScript projects.
Coding conventions are style guidelines for programming. They typically cover:
Coding conventions secure software quality:
Coding conventions can be documented rules for teams to follow, or just be your individual coding practice.
This page describes the general JavaScript code conventions used by W3Schools. |
At W3schools we use camelCase for identifier names (variable and function). All names start with a letter.
At the bottom of this page, you will find a wider discussion about naming rules.
firstName = "John";
lastName = "Doe";
price = 19.90;
discount = 0.10;
fullPrice = price * 100 / discount;
It is good coding practice to put all declarations at the top of each script or function.
This gives better, cleaner code, and reduces the possibility of accidental re-declarations.
var firstName, lastName;
var price, discount, fullPrice;
firstName = "John";
lastName = "Doe";
price = 19.90;
discount = 0.10;
fullPrice = price * 100 / discount;
This also goes for variables in loops:
var i;
for (i = 0; i < 5; i++)
Since JavaScript moves the declarations to the top anyway (JavaScript hoisting), it is always a good rule. |
Always put spaces around operators, and after commas:
x = 5 + 6; // Good
x=5+6 // Bad
[40, 100, 1, 5] // Good
[40,100,1,5] // Bad
Always use 4 spaces for indentation of code blocks:
function toCelsius(fahrenheit) {
return (5/9) * (fahrenheit-32);
}
for (i = 1; i < 50; i++) {
sum += i;
}
Do not use tabs (tabulators) for indentation. Text editors interpret tabs differently. |
For readability, avoid lines longer than 80 characters.
If a JavaScript statement does not fit on one line, the best place to break it, is after an operator or a comma.
document.getElementById("demo").innerHTML =
"Hello Dolly.";
Coding conventions are not used by computers. Most rules have little impact on the execution of programs.
Indentation and extra spaces are not significant in small scripts.
For code in development, readability should be preferred. Larger production scripts should be minifyed.
Always use the same naming convention for all your code. For example:
Should you use hyp-hens, camelCase, or under_scores in variable names?
This is a question programmers often discuss. The answer depends on who you ask:
Hyphens in HTML and CSS:
HTML5 attributes can start with data- (data-quantity, data-price).
CSS uses hyphens in property-names (font-size).
Hyphens can be mistaken as subtraction attempts. Hyphens are not allowed in JavaScript names. |
Underscores:
Many programmers prefer to use underscores (date_of_birth), especially in SQL databases.
Underscores are often used in PHP documentation.
CamelCase:
CamelCase is often preferred by C programmers.
camelCase:
camelCase is used by JavaScript itself, by jQuery, and other JavaScript libraries.
Don't start names with a $ sign. It will put you in conflict with many JavaScript library names. |
Avoid global variables, avoid new, avoid ==, avoid eval()
Avoid using global variables.
This includes all data types, objects, and functions.
Global variables and functions can be overwritten by other scripts.
Use local variables instead, and learn how to use closures.
All variables used in a function should be declared as local variables.
Local variables must be declared with the var keyword, otherwise they will become global variables.
Strict mode does not allow undeclared variables. |
Always treat numbers, strings, or booleans as primitive values. Not as objects.
Declaring numbers, strings, or booleans as objects, slows down execution speed, and produces nasty side effects:
var x = "John";
var y = new String("John");
(x === y) // is false because x is a string and y is an object.
var x1 = {}; // new object
var x2 = ""; // new primitive string
var x3 = 0; // new primitive number
var x4 = false; // new primitive boolean
var x5 = []; // new array object
var x6 = /()/; // new regexp object
var x7 = function(){}; // new function object
Beware that numbers can accidentally be converted to strings or NaN (Not a Number).
JavaScript is loosely typed. A variable can contain different data types, and a variable can change its data type:
var x = "Hello"; // typeof x is a string
x = 5; // changes typeof x to a number
When doing mathematical operations, JavaScript can convert numbers to strings:
var x = 5 + 7; // x.valueOf() is 12, typeof x is a number
var x = 5 + "7"; // x.valueOf() is 57, typeof x is a string
var x = "5" + 7; // x.valueOf() is 57, typeof x is a string
var x = 5 - 7; // x.valueOf() is -2, typeof x is a number
var x = 5 - "7"; // x.valueOf() is -2, typeof x is a number
var x = "5" - 7; // x.valueOf() is -2, typeof x is a number
var x = 5 - "x"; // x.valueOf() is NaN, typeof x is a number
Subtracting a string from a string, does not generate an error but returns NaN (Not a Number):
"Hello" - "Dolly" // returns NaN
The == comparison operator always converts (to matching types) before comparison.
The === operator forces comparison of values and type:
0 == ""; // true
1 == "1"; // true
1 == true; // true
0 === ""; // false
1 === "1"; // false
1 === true; // false
points = [40, 100, 1, 5, 25, 10, ];
person = {firstName:"John", lastName:"Doe", age:46, }
Some JSON and JavaScript engines will fail, or behave unexpectedly.
If a function is called with a missing argument, the value of the missing argument is set to undefined.
Undefined values can break your code. It is a good habit to assign default values to arguments.
function myFunction(x, y) {
if (y === undefined) {
y = 0;
}
}
Or, even simpler:
function myFunction(x, y) {
y = y || 0;
}
Read more about function parameters and arguments at Function Parameters
The eval() function is used to run text as code. In almost all cases, it should not be necessary to use it.
Because it allows arbitrary code to be run, it also represents a security problem.
How to speed up your JavaScript code.
Loops are often used in programming.
Every statement inside a loop will be executed for each iteration of the loop.
Search for statements or assignments that can be placed outside the loop.
Accessing the HTML DOM is very slow, compared to other JavaScript statements.
If you expect to access a DOM element several times, access it once, and use it as a local variable:
obj = document.getElementByID("demo");
obj.innerHTML = "Hello";
Keep the number of elements in the HTML DOM small.
This will always improve page loading, and speed up rendering (page display), especially on smaller devices.
Every attempt to search the DOM (like getElementsByTagName) is will benefit from a smaller DOM.
Don't create new variables if you don't plan to save values.
Often you can replace code like this:
var fullName = firstName + " " + lastName;
document.getElementById("demo").innerHTML = fullName;
With this:
document.getElementById("demo").innerHTML = firstName + " " + lastName
Putting your scripts at the bottom of the page body, lets the browser load the page first.
While a script is downloading, the browser will not start any other downloads. In addition all parsing and rendering activity might be blocked.
The HTTP specification defines that browsers should not download more than two components in parallel. |
An alternative is to use defer="true" in the script tag. The defer attribute specifies that the script should be executed before the page has finished parsing, but it only works for external scripts.
If possible, you can add your script to the page by code, after the page has loaded:
<script>
window.onload = downScripts;
function downScripts() {
var element = document.createElement("script");
element.src = "myScript.js";
document.body.appendChild(element);
}
</script>
Avoid using the with keyword. It has a negative effect on speed. It also clutters up JavaScript scopes.
The with keyword is not allowed in strict mode.
In JavaScript, some identifiers are reserved words and cannot be used as variables or function names.
All modern browsers fully support ECMAScript 3 (ES3, the third edition of JavaScript from 1999).
ECMAScript 4 (ES4) was never adopted.
ECMAScript 5 (ES5, released in 2009) is the latest official version of JavaScript.
Time passes, and we are now beginning to see complete support for ES5 in all modern browsers.
In JavaScript you cannot use these reserved words as variables, labels, or function names:
abstract |
arguments |
boolean |
break |
byte |
case |
catch |
char |
class* |
const |
continue |
debugger |
default |
delete |
do |
double |
else |
enum* |
eval |
export* |
extends* |
false |
final |
finally |
float |
for |
function |
goto |
if |
implements |
import* |
in |
instanceof |
int |
interface |
let |
long |
native |
new |
null |
package |
private |
protected |
public |
return |
short |
static |
super* |
switch |
synchronized |
this |
throw |
throws |
transient |
true |
try |
typeof |
var |
void |
volatile |
while |
with |
yield |
|
|
Words marked with* are new in ECMAScript5
You should also avoid using the name of JavaScript built-in objects, properties, and methods:
Array |
Date |
eval |
function |
hasOwnProperty |
Infinity |
isFinite |
isNaN |
isPrototypeOf |
length |
Math |
NaN |
name |
Number |
Object |
prototype |
String |
toString |
undefined |
valueOf |
JavaScript is often used together with Java. You should avoid using some Java objects and properties as JavaScript identifiers:
getClass |
java |
JavaArray |
javaClass |
JavaObject |
JavaPackage |
JavaScript can be used outside HTML. It can be used as the programming language in many other applications.
In HTML you must (for portability you should) avoid using the name of HTML and Windows objects and properties:
alert |
all |
anchor |
anchors |
area |
assign |
blur |
button |
checkbox |
clearInterval |
clearTimeout |
clientInformation |
close |
closed |
confirm |
constructor |
crypto |
decodeURI |
decodeURIComponent |
defaultStatus |
document |
element |
elements |
embed |
embeds |
encodeURI |
encodeURIComponent |
escape |
event |
fileUpload |
focus |
form |
forms |
frame |
innerHeight |
innerWidth |
layer |
layers |
link |
location |
mimeTypes |
navigate |
navigator |
frames |
frameRate |
hidden |
history |
image |
images |
offscreenBuffering |
open |
opener |
option |
outerHeight |
outerWidth |
packages |
pageXOffset |
pageYOffset |
parent |
parseFloat |
parseInt |
password |
pkcs11 |
plugin |
prompt |
propertyIsEnum |
radio |
reset |
screenX |
screenY |
scroll |
secure |
select |
self |
setInterval |
setTimeout |
status |
submit |
taint |
text |
textarea |
top |
unescape |
untaint |
window |
In addition you should avoid using the name of all HTML event handlers.
Examples:
onblur |
onclick |
onerror |
onfocus |
onkeydown |
onkeypress |
onkeyup |
onmouseover |
onload |
onmouseup |
onmousedown |
onsubmit |
|
In addition to reserved words, there are also some nonstandard keywords used in some JavaScript implementations.
One example is the const keyword used to define variables. Some JavaScript engines will treat const as a synonym to var. Other engines will treat const as a definition for read-only variables.
Const is an extension to JavaScript. It is supported by the JavaScript engine used in Firefox and Chrome. But it is not a part of the JavaScript standards ES3 or ES5. Do not use it.
JSON is a format for storing and transporting data.
JSON is often used when data is sent from a server to a web page.
* JSON uses JavaScript syntax, but the JSON format is text only. |
This JSON syntax defines an employees object: an array of 3 employee records (objects):
{"employees":[
{"firstName":"John", "lastName":"Doe"},
{"firstName":"Anna", "lastName":"Smith"},
{"firstName":"Peter", "lastName":"Jones"}
]}
The JSON format is syntactically identical to the code for creating JavaScript objects.
Because of this similarity, a JavaScript program can easily convert JSON data into native JavaScript objects.
JSON data is written as name/value pairs, Just like JavaScript object properties.
A name/value pair consists of a field name (in double quotes), followed by a colon, followed by a value:
"firstName":"John"
JSON objects are written inside curly braces.
Just like in JavaScript, objects can contain multiple name/values pairs:
{"firstName":"John", "lastName":"Doe"}
JSON arrays are written inside square brackets.
Just like in JavaScript, an array can contain objects:
"employees":[
{"firstName":"John", "lastName":"Doe"},
{"firstName":"Anna", "lastName":"Smith"},
{"firstName":"Peter", "lastName":"Jones"}
]
In the example above, the object "employees" is an array. It contains three objects.
Each object is a record of a person (with a first name and a last name).
A common use of JSON is to read data from a web server, and display the data in a web page.
For simplicity, this can be demonstrated using a string as input (or read more in our JSON tutorial):
First, create a JavaScript string containing JSON syntax:
var text = '{ "employees" : [' +
'{ "firstName":"John" , "lastName":"Doe" },' +
'{ "firstName":"Anna" , "lastName":"Smith" },' +
'{ "firstName":"Peter" , "lastName":"Jones" } ]}';
Then, use the JavaScript built-in function JSON.parse() to convert the string into a JavaScript object:
var obj = JSON.parse(text);
Finally, use the new JavaScript object in your page:
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML =
obj.employees[1].firstName + " " + obj.employees[1].lastName;
</script>
In JavaScript, objects are king. If you understand objects, you understand JavaScript. |
In JavaScript, almost "everything" is an object.
In JavaScript, all values, except primitive values, are objects.
Primitive values are: strings ("John Doe"), numbers (3.14), true, false, null, and undefined.
JavaScript variables can contain single values:
var person = "John Doe";
Objects are variables too. But objects can contain many values.
The values are written as name : value pairs (name and value separated by a colon).
var person = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"};
A JavaScript object is an unordered collection of variables called named values. |
The named values, in JavaScript objects, are called properties.
Property |
Value |
firstName |
John |
lastName |
Doe |
age |
50 |
eyeColor |
blue |
Objects written as name value pairs are similar to:
Methods are actions that can be performed on objects.
Object properties can be both primitive values, other objects, and functions.
An object method is an object property containing a function definition.
Property |
Value |
firstName |
John |
lastName |
Doe |
age |
50 |
eyeColor |
blue |
fullName |
function() {return this.firstName + " " + this.lastName;} |
JavaScript objects are containers for named values, called properties and methods. |
You will learn more about methods in the next chapters.
With JavaScript, you can define and create your own objects.
There are different ways to create new objects:
In ECMAScript 5, an object can also be created with the function Object.create(). |
This is the easiest way to create a JavaScript Object.
Using an object literal, you both define and create an object in one statement.
An object literal is a list of name:value pairs (like age:50) inside curly braces {}.
The following example creates a new JavaScript object with four properties:
var person = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"};
Spaces and line breaks are not important. An object definition can span multiple lines:
var person = {
firstName:"John",
lastName:"Doe",
age:50,
eyeColor:"blue"
};
The following example also creates a new JavaScript object with four properties:
var person = new Object();
person.firstName = "John";
person.lastName = "Doe";
person.age = 50;
person.eyeColor = "blue";
The two examples above do exactly the same. There is no need to use new Object(). |
The examples above are limited in many situations. They only create a single object.
Sometimes we like to have an "object type" that can be used to create many objects of one type.
The standard&nbs