JavaScript 101.
I know JavaScript - Show me!
JavaScript is a real language. Building a modern dynamic website without knowing it is nonsense. A lot of people working on web applications and web sites learnt the language on the job. Code written is often hard to understand and hard to maintain. It doesn't follow best practices or standard rules which provoke strange behaviours and bugs. Taking time to understand the fundamentals is really important! By doing so you can stop being a normal human and become a true web developer.
History
JavaScript was introduced by Brendan Eich in 1995 for Netscape Communications. It was submitted few months later to Ecma International for consideration as an industry standard. The result standard version is ECMAScript.
Even if the name comes from a partnership between Netscape and Sun Microsystems (distributor of Java) JavaScript is not a "light" version of Java.
Definition & properties
JavaScript is a scripting language that supports multiple programming styles. It differs from other languages such as C++, Java or PHP with its dynamic behaviour, its first-class functions and its prototype-based inheritance.
JavaScript lovers consider these features as the force of the language. It's very common for people who try to write JavaScript like they write code in other languages to hate it. Don't make this mistake!
Usages
Even if it was originally designed to work in a browser environment, JavaScript is now used on several different platforms. Here are a few examples :
- Web server
- Browser addons/extensions
- Mobile applications
- Databases consoles
- OpenOffice scripts/macros
- Java applications
Basic syntax
JavaScript is case-sensitive. Lines end by semicolon ;
. Block are delimited curly brackets by { }
. Comments are between /* */
for multiple lines or after //
for one line.
Variables & Types
In JavaScript, Typing is dynamic. Therefore, there is NO type declaration before variable names. Instead we use a unique keyword : var
. Note that a variable can be declared several times. If it's non-declared, the variable is automatically allocated at the first use.
Number
Numbers like in any other languages are really important. Don't forget that a computer is primarly a super calculator. Integers and floats have the same type : Number
. Of course, a variable can only be identified as type Number
at execution time..
If you want to manipulate numbers, the objects Number
and Math
has lots of useful properties and methods. The other useful way to manipulate them is operators of course. See reference for more details.
var i;
i = 2;
In this example we see that floats can have strange behaviour, don't forget the internals of the float storage. It's stored as IEEE 754.
var i = -5.01;
j = 2;
j = i + 1.12;
var k = 0.1 + 0.2
var l = new Number(7);
var a = 10 / 0;
var b = -10 / 0;
var c = Math.sqrt(-1);
String
Strings are really simple. Quotes or double quotes, no differences, some text in it and you're done. The most important property of a String when it comes to manipulation is length
. It's not the only one, the String
object contains a lot of useful properties and methods, see reference for more details.
The other way a good programer should manipulate string is regular expressions and as expected, JavaScript provides a regex engine and a RegExp
object. Regex can be complicated to master, but the game is worth it since it's a multi language concept. See reference for more details.
var a = "";
var b = 'There is no spoon.';
var c = "Only human.";
var d = 'pill="red"';
var e = "Free your mind.";
var f = "You're empty.\nSo are you.";
var g = new String("Welcome to the real world.");
Boolean
Nothing fancy here, true
of false
. You'll see later that other types of variables (Number, String...) can by evaluated as booleans according to some rules.
var realWorld = false;
var matrix = true;
var a = new Boolean(true);
null and undefined
Both null
and undefined
are used for absence of a value. One is used when the variable has been initialiazed : null
. The other one is used when the variable has not been initialized : undefined
. It can be returned by function that have no return
statement.
var neo;
neo = null;
Arrays
An array is an ordered colleciton of values. Values can be of different types. Each value is called an element and is positioned in the array with a numeric index starting at zero.
The Array
object has several properties and methods. The most important property is length
, it contains the size of the array. See reference for more details.
Creating
The easiest way to create an array is with square brackets and comma separated values in it. Note that you can create an array with 4 undefined elements, length will be 4.
var a = [];
var b = new Array();
var c = [,,,,];
var d = new Array(4);
var e = ["the", 1, true];
var f = new Array("the", 1, true);
Reading and writing
Reading and writing in arrays is done with brackets and equal assignment operator. Note that reading from and index that haven't been initialized doesn't generate any errors, it returns undefined
.
You can insert values in non consecutive indexes, it create a what's called a "sparse array". The length is updated to maximum index + 1.
var a = ["white"];
var b = a[0];
var c = a[100];
a[1] = 3.14;
var i = 2;
a[i] = 3;
a[i + 1] = "rabbit";
a[a[i]] = a[0];
var d = a.length;
Adding and deleting
To add and delete elements from an array, you can use the methods from the Array
object. There's a lot of useful ones, from simple pop
and push
to more complex ones like splice
. See reference for more details.
var a = ["follow", "the", "white", "rabbit"];
var b = a.pop();
var c = a.push("RABBIT");
var d = a.shift();
var e = a.unshift("FOLLOW");
var f = a.splice(2, 1);
var g = a.splice(1, 2, "ME");
Operators
Operators are really powerful in JavaScript. Unlike in some other languages like C, operators are not only used to do maths, they are also very useful with strings.
Arithmetics
Arithmetics operators work the same way as a lot of other programming languages. Note that +
is used to concatenate strings.
var a = 6 + 4;
var b = -a;
var c = 6 - 4;
var d = 1, e = ++d;
var f = 1, g = f++;
var h = 7, i = --h;
var j = 7, k = j--;
var l = 3 * 3
var m = 10 / 3
var n = 10 % 3
var o = "Dodge" + " " + "this."
Equality
A particularity of JavaScript is the two kinds of equality comparison : strict and type-converting. Just remember that strict equal ===
compares both types and values and type-converting equal ==
converts one type to the other and just compares values.
Best practice is to always use the strict equality. It prevents a lot of mistakes.
var a = "2" == 2;
var b = "2" != 2;
var c = "2" === 2;
var d = "2" !== 2;
Comparison
Like arithmetics, comparison operators work the same way as a lot of other programming languages. Note that these operators can be used to compare string.
var a = 2 > 2;
var b = 2 <= 2;
var c = "2" >= 2;
var d = 2 < 2;
var e = 2 <= 2;
var f = 'abc' < 'def'
Logical
var a = true && false;
var b = true || false;
var c = !true;
Bitwise
Bitwise operators help programmers to use numbers like sequences of 32 bits (zeros and ones). It's not always easy to understand what's going on but it's very useful, for example if you're implementing bitmasks.
var a = 42 & 2
var b = 7 | 2
var c = 7 ^ 2
var d = ~8
var e = 1 << 3
var f = 8 >> 2
var g = -1 >> 2
var h = -1 >>> 2
Assignement
Assignement operators saves you some place and can improve code readability. Use them carefuly!
var a = 1, b = 0;
a += b
a -= b
a *= b
a /= b
a %= b
a <<= b
a >>= b
a >>>= b
a &= b
a |= b
a ^= b
in
The in
operator is used to verify if a property is specified on an object. Be careful when you use it.
var a = [1,9,4];
var b = (2 in a);
var c = (9 in a);
var d = (length in a);
typeof
typeof
is used at compilation time to verify the type of a variable.
var a = 3;
var b = typeof a;
var c = "";
var d = typeof c;
var e = true;
var f = typeof e;
Type conversions
JavaScript is not statically typed but you can determine the type of a variable at execution time. Conversion from one type to another can be done explicitly or implicitly. It's really important to understand implicit ones, they can help you to avoid strange behaviours and bugs.
Explicit
Explicit conversions can for example help you to convert a string to a number. Note that even if integers and floats are both number, using parseInt
on a float removes the decimals and makes it by definition an integer.
var a = Number("10");
var b = Number(false);
var c = parseInt("10", 10);
var d = parseInt(10.2);
var e = parseFloat("10.2");
var a = String(false);
var b = String(10);
var c = String(10.2);
var d = (10).toString();
var a = Boolean(10);
var b = Boolean(0);
var c = Boolean(0.3);
var d = Boolean("true");
Implicit
There's a lot of ways to convert a string to a number. Performances can differ a lot depending on the technique used and the plateform. A shorter syntax is often prefered for bandwith uses.
Look carefully how the +
operator behaves with strings and numbers.
var a = +"10";
var b = "10" >> 0;
var c = "10" * 1;
var d = ~~"10";
var e = "2" * "5";
var a = 10 + "10";
var b = "10" + "10";
var c = 10 + " agents";
var d = 10 + 10 + " agents";
var a = !!'morpheus';
var b = !!'';
var c = !!'0';
var d = !!'1';
Summary
Here's a little summary of conversions results. Pay attention especially to "anything to boolean" conversions, it can save you some time when used in if
conditions.
Value | String | Number | Boolean
|
undefined | "undefined" | NaN | false
|
null | "null" | 0 | false
|
true | "true" | 1 |
|
false | "false" | 0 |
|
"" (empty string) | | 0 | false
|
"1.2" (nonempty, numeric) | | 1.2 | true
|
"one" (nonempty, non-numeric) | | NaN | true
|
0 | "0" | | false
|
-0 | "0" | | false
|
NaN | "NaN" | | false
|
Infinity | "Infinity" | | true
|
-Infinity | "-Infinity" | | true
|
1 (finite, non-zero) | "1" | | true
|
[] (empty array) | "" | 0 | true
|
[9] (1 numeric elt) | "9" | 9 | true
|
['a'] (any other array) | use join() method | NaN | true
|
Conditionnal
In JavaScript, conditionnal statements behaves pretty much like in other common languages.
Note that the conditional ternary operator should only be used in simple cases. It is often use for variable assignment and its usage is synonym of shorter syntax and readability. If you think it doesn't make your code better, use a classic if
.
if/else
In this case, normal equality is handy, used with null
, it can test null || undefined
.
if (username == null) {
username = "Trinity";
}
if (bulletCount === 1) {
bulletCount += ' bullet';
} else {
bulletCount += ' bullets';
}
var user = (name == null) ? 'default user' : name;
switch
Switch usage is often advised when you have too much if statements. Don't forget the break
keyword. Note that you can use string unlike some other languages.
var quote;
switch (characterName) {
case 'Smith':
quote = 'Goodbye, Mr. Anderson...';
break;
case 'Neo':
quote = 'I know kung fu.';
break;
default:
quote = 'What is the Matrix?';
break;
}
loops
for (var i = 0; i < 10; i++) {
doSomething();
}
var count = 0;
while (count < 10) {
doSomething();
count++;
}
var count = 100;
do {
doSomething();
} while (--count > 0);
for...in loops
for..in loops are used to iterate over properties of an object.
Array indexes are just enumerable properties with integer names. Therefore, for...in loops could be used to enumerate elements of an array.
Because of performance issues and in order to avoid bugs, use classic for loops instead of for..in with arrays.
var a = [123, 456, 789];
for (var i in a) {
doSomething(a[i]);
}
Because of performance issues and in order to avoid "bugs" and "strange behaviours", use classic for loops instead of for..in with arrays.
Simple functions
Functions are declared with the function
keyword. There's no return type and no variable type for the arguments.
function functionName(var1, var2, var3) {
return returnVal;
}
function useArgs(var1, var2, var3) {
var a = arguments.length;
var result = "";
for (var i = 0; i < a; i++) {
result += " " + arguments[i];
}
return result;
}
var b = useArgs("Déjà", "vu");
Variable scope
The scope of a variable is the region of your code in which it is defined. JavaScript has a very specific way of handling scope. Scope can be altered by function
s and the var
keyword.
Note that statements like if
, for
... doesn't change scope of variables. See reference for more details.
Global vs. local
Variables declared outside of any function are defined everywhere in your code. They are considered global.
Variables declared inside a function are defined only within the function body. They are considered local to the function.
var name = "Andy";
function foo() {
var lastName = "WACHOWSKI";
return name + ' ' + lastname;
}
foo();
var a = lastName;
Don't forget var
If you ommit the var
keyword inside a function, the variable is automatically considered global. It can have serious side effects. It's considered bad practice, you shouldn't use this.
var i = 1;
function foo() {
var i = 3;
}
foo();
var a = i;
var i = 1;
function foo() {
i = 3;
j = 4;
}
foo();
var a = i;
var b = j;
Integration
The best way to integrate JavaScript in a web page is through a JavaScript file and a link to it in your HTML page. The link can be placed in head
or body
it really depends on the situation.
<!DOCTYPE html>
<html>
<head>
<script src="myscript1.js"></script>
<script> </script>
</head>
<body>
<script src="myscript2.js"></script>
</body>
</html>
Avoid direct JavaScript in HTML documents, it's a bad practice. It breaks the structure/behaviour separation. Code can't be reused on other pages. It also prevents you from having a changeable and maintenable code.
Putting your scripts at the just before the </body>
is a good practice. We'll see that in details in performances lesson.
Browser objects
Every JavaScript plateform/environment adds objects with global scope. They're meant to provide helpful features to developers. In web browsers the most important ones are : document
and window
.
Another object is present but only in modern browsers : console
. Since it's not standard, implementations may differ, see references for more details. Remember that older browsers don't support it, so don't let console.log('foo')
etc... in production code.
var title = document.title;
var href = window.location.href;
var userAgent = window.navigator.userAgent;
window.alert('Never send a human to do a machine\'s job.');
var bluePill = confirm('Take the blue pill?');
var name = prompt('What is your name?');
console.log('Perhaps we are asking the wrong questions.');
console.error('Nothing. Just had a little déjà vu.');
console.info('A déjà vu is usually a glitch in the Matrix.');
console.warn('The Matrix is a system, Neo. That system is our enemy.');
Your browser should have two very useful tools to work with JavaScript :
- JavaScript Debugger
- JavaScript Console
There's also great tools on the web :
Compatibility
Even if JavaScript has been standardized to ECMAScript, each platform doesn't always support all the latest features. You should always read documentation and look up if it's supported. You should also test your code over the different browsers of your audience.
There's often two (or more) ways to do the same thing in JavaScript. It's not because two browsers have feature X and Y that they implemented it the same way. Performances can be very different. As always : read documentation and test...