What you should know about if you are new to Javascript
Unlike server-side or desktop development, where you can use whatever language and whatever framework you want, in client-side development you're pretty much stuck with Javascript. There are some languages that compile to Javascript, and if you really really don't like Javascript, you have some options that you might prefer, like Script#, WebSharper, Dart, CoffeeScript, ClojureScript, Opa, and many others. That said, for better or for worse, Javascript really is the lingua franca of the web. That means if you want to make a web application, you'll probably end up needing to learn Javascript whether you like it or not.
In this article, I will try to go over the most important points about Javascript that you should know about. I am assuming that you are already a somewhat experienced programmer and that you are learning or are intending to learn Javascript. This article is primarily geared towards C# and Java developers, but even if you are accustomed to something different you might still learn something useful.
Javascript's Language Family
Javascript's name deceptively suggests that it is based on Java and, like Java, is part of the C language family. Javascript isn't really in a language family. Javascript is really just a kitchen sink conglomeration of features that its creator, Brendan Eich, liked in other languages and was able implement in two weeks. Essentially, Javascript is the bastard child of Java, Scheme, Perl, and Self.
On a superficial level, you should be able to get accustomed to Javascript quickly because its syntax is borrowed almost exclusively from its Java ancestry. Javascript has all the curly braces, semicolons, and the if
-for
-while
-do
-switch
-throw
-catch
-finally
control structures that you already know and love. You should relish this as long as you can, because this is as far as the similarity between Java/C# and Javascript goes.
Dynamic Typing
Javascript is dynamically typed, whereas C# and Java are statically typed. This means that in Javascript variables can change their type, and that you don't ever need to explicitly denote the type of variables or the return type of functions.
If you saw code like this in a statically typed language
int x = 5;
x = "hello";
you would rightfully expect the compiler to start throwing up a big nasty TypeError
. Javascript, on the other hand, will happily run this code even though the type changed.
var x = 5;
x = "hello";
Because variables can change types, the compiler can't know as much information about them. You should expect the tools for Javascript to be inferior to those of Java/C# as far as useful niceties like code completion go. Fewer mistakes will be caught at compile time and you will have to do more runtime debugging than you are probably used to.
Weak Typing
Javascript is weakly typed. This means that Javascript will do all sorts of crazy implicit type conversions and you had better be careful or it will bite you. In strongly typed languages, the compiler will think you're insane if you try to add a number and a string 2 + "3"
or do arithmetic with booleans and arrays true + ([] - false)
. Javascript, on the other hand, will happily plod along and convert numbers to strings, booleans and empty arrays to numbers, and just about anything to booleans, all behind the scenes.
Weak typing has all sorts of consequences that you might not expect, but there are two important ones you should know about.
First, Javascript has an ==
operator. You would expect it to act like the ==
operator in other languages, but, unfortunately, it doesn't. If the two operands are of different types, Mr. Javascript will try to unify their types with whatever conversion tickles his fancy, and then check for equality. All of these expressions return true in Javascript, contrary to what you would reasonably expect:
123 == "123"
true == 1
false == "0"
[] == ""
{} == "[object Object]"
Fortunately, Javascript has strict equality operators ===
and !==
that always return false if the two operands are of different types. You should almost always use them instead of the ==
and !=
operators.
Second, Javascript will always convert an expression inside of an if
statement to a boolean. The following values will evaluate to false
in an if
predicate. These are called "falsy" values.
false
null
undefined
0
""
NaN
Everything else evaluates to true, or is a "truthy" value.
Numbers
Javascript only has one number type. It's equivalent to the double
type you are familiar with. Keep this in mind, because integer division might not behave how you expect. Also keep in mind that bit shifting and bitwise manipulation operations are expensive in Javascript because numbers have be converted to integers before the bit operation is done, and then converted back to doubles.
Arrays
There is only one list type in Javascript, and Javascript calls them arrays. This single data type is used in Javascript where you might use lists, arrays, vectors, sets or tuples in other languages. The array can have dynamically changed length, and the elements in the array do not have to be the same type.
Basically, you can declare an array like this
var array1 = [];
var array2 = [1, "hello", null, ["bye", 0]];
It's pretty simple, but I recommend reading over the array functions in Javascript to familiarize yourself with what is available and how you can work with them.
Objects
Objects are one of the best features of Javascript because of their versatility. An object in Javascript is like an associative array or a dictionary. On the left you have string keys or names and on the right you can have any Javascript value, including functions and other objects.
In Java/C# you use classes a lot. In Javascript, you can use objects for the same purpose much more concisely.
This is a contrived person class
class Person
{
public string name = "John";
public int age = 25;
public string occupation = "programmer";
}
In Javascript, you can accomplish the same task with an object literal
var person = {
name: "John",
age: 25,
occupation: "programmer"
};
But let's suppose you wanted to get fancy with a full-blown class with a constructor, private fields, and a method.
class Person
{
private string name;
private int age;
private string occupation;
public Person(string name, int age, string occupation)
{
this.name = name;
this.age = age;
this.occupation = occupation;
}
public string GetDescription()
{
return name + " is a " + age + " year old person that earns money as a " + occupation + ".";
}
}
Now you can make a new person and get his description with code like
Person John = new Person("John", 25, "programmer");
string biographyOfJohn = John.GetDescription();
Javascript doesn't have classes. Javascript has something that I would argue is more intuitive and more concise: objects. Let's observe how objects can work by porting our Person class to Javascript.
function Person(name, age, occupation) {
return {
name: name,
age: age,
occupation: occupation,
getDescription: function() {
return name + " is a " + age + " year old person that earns money as a " + occupation + ".";
}
};
}
Now, of course, you can call the Person function which returns an object which you can use to get a description of somebody.
var John = Person("John", 25, "programmer");
var biographyOfJohn = John.getDescription();
Functions
Functions in Javascript, unlike C# and Java, are first class values: you can assign them to variables, pass them to functions, have them returned from functions, and have them be elements of arrays and values in objects. This is an awesome feature.
Explaining why this is awesome is outside the scope of this article, but it is awesome, and if you aren't familiar with this concept, I highly recommend reading about functional programming in Javascript, or even about the functional programming paradigm in general.
Anyway, the function syntax in Javascript is, for the most part, pretty straightforward. You have two options,
function name(arguments) {
return returnValue;
}
or
var name = function(arguments) {
return returnValue;
}
The only difference is that the first automatically "hoists" itself to the top of the scope, allowing you to call it in the code before it is declared. (Read more about hoisting in Javascript) The second will only let you call it after it has been declared.
Scope
Javascript only has function scope, rather than block scope in C#/Java. This will bite you if you write some code like this
var x = 45;
if(condition) {
var x = 35;
}
With block level scope, you would expect x to be local to its block and not affect the outer x. In Javascript, both are considered in the same scope and thus assigning to the inner x will change the outer x.
Fortunately, code quality tools like JSHint can find this sort of problem and warn you about it.
Accidental Global Scope
Always make sure you use the `var` keyword when you declare a variable. If you don't, Javascript will automatically assume it's global. That's bad: it can cause subtle errors that are hard to debug.
var globalVar = "global variable";
otherGlobalVar = "other global variable";
function doStuff() {
alsoGlobal = "unfortunately, this is also a global variable";
}
All of the variables declared in this sample are global. globalVar
is ok, although you generally should avoid excessive use of global variables. otherGlobalVar
is generally considered bad form, and alsoGlobal
is very bad and likely to cause a bug.
Again, make sure you use a tool like JSHint, which will catch mistakes like this for you.
The DOM
This isn't about Javascript as a language itself, per se, but rather the library that it uses to manipulate web pages with the Document Object Model: it's terrible. Different browsers don't agree how things work, it's terribly verbose, and I don't recommend wasting your time with it. Do yourself a favor by using a DOM-abstraction framework like jQuery.
That's all, folks!
I am sure you will encounter other surprising aspects of Javascript, but I hope I've covered the most egregious ones. If you are planning to pursue Javascript, there are a few links I would like to recommend: