Introduction to JavaScript

Welcome to my JavaScript tutorial, my name is Adam Wexler. I have been involved in Web development for 5 years, and am currently studying Computer Science at USC. Like many Web developers in the world, understanding how to implement plugins using JavaScript libraries like jQuery was the extent of my JavaScript knowledge for many years. I recently decided to sit down and spend some time learning JavaScript and having read some fantastic blog posts on the way, I was inspired to write my own tutorial.

There is no question that JavaScript is an invaluable tool for anyone interested in web development – every web browser supports it, even mobile Web browsers. JavaScript relies on the DOM to connect it with the markup and styles of elements on a Web page.

What is the DOM?
A Web page is a document. This document can be either displayed in the browser window, or as the HTML source. But it is the same document in both cases. The Document Object Model (DOM) provides another way to represent, store and manipulate that same document. The DOM is a fully object-oriented representation of the web page, and it can be modified with a scripting language such as JavaScript.

Despite the fact that JavaScript seems to have picked up a bad reputation because of browser-compatibility issues on older browsers and because of the overwhelming complexity of using the DOM, this has been circumvented by the creation of fantastic JavaScript libraries like jQuery. A very common misconception is that you can go right into using jQuery or other JavaScript libraries without learning JavaScript first – this is not the case! You can’t run without first learning how to walk. jQuery was written in JavaScript, and as such, all the code you write is still JavaScript. Once you know JavaScript, there are plenty of helpful libraries out there that will help you easily control and manipulate the DOM.

Most modern browsers contain a Web Console (Chrome/Firefox) which allows you to execute JavaScript on the fly. My tutorial is filled with examples, all of which I recommend you run in your console. Some of the examples will display text in your console, which I always comment in:

var number = 5;
console.log(number); // 5

More info: console.log(obj1 [, obj2, ..., objN)

The focus of this tutorial is not to jump right in to using JavaScript on websites (a tutorial on the DOM could be just as long as one about JavaScript), but rather familiarize you with the syntax so that you may more easily use libraries or modify others code. This tutorial does not assume any prior experience in writing JavaScript, so please let me know if you have any questions, however trivial. While what I've written is meant to be comprehensive, I did not include how to use JavaScript to manipulate the DOM. Instead, this tutorial will prepare you to use JavaScript libraries, such as jQuery and d3.js.

Table of Contents

  1. Variables, primitive types, operators, and expressions
    • Operators and Statements
      • Comparison operators
      • String operators
      • Integer parsing
  2. Functions
    • Passing parameters in JavaScript
    • Anonymous Functions
  3. Arrays, objects, and classes
    • Arrays
    • Objects
    • Custom Objects
      • Variable scope and closure
      • Functions in objects
      • Function chaining
      • Prototype based programming
      • Static variables
  4. Inheritance
    • The prototype
      • Prototype chain
      • Accessors and Mutators
  5. Additional Resources
    • Defining JavaScript as a weakly and dynamically typed language
      • Strongly typed and weakly typed languages
      • Static and dynamic typing
  6. Advanced Topics
    • Callbacks
    • Array iteration method
      • Array.filter
      • Array.forEach and Array.map

#Variables, primitive types, operations, and expressions

Variables are declared using the var keyword. Notice that although every variable is declared using the same keyword, their values still retain different types. Here are some of the primitive types of JavaScript.

var truthy = true, 
    five   = 5,
    word   = "Anything!";
var x = null;

typeof(truthy); // boolean
typeof(five);   // number
typeof(word);   // string
typeof(x);      // object
typeof(asdf);   // undefined    

More info: typeof

To var, or not to var?

If you're in a function then using var will create a local variable. If you don't use var it will look up the scope chain until it finds the variable or hits the global scope (at which point it will create it).

The assignment expression, =, returns the right side value of the assignment after assigning it.

var f;
console.log(f);     // undefined
console.log(f = 3); // 3
console.log(f);     // 3

# Operators and Statements

# Comparison operators

Operators are used to compare two different values. Most operators behave as you'd expect; > and < are used to compute greater or less than as you'd expect.

Comparing for equality is a bit more challenging. Typically you use ===, the Strict Equals operator. === will always return false when the operands are of different type. == is the Equals operator. This allows you to compare "truthy" and "falsy" values with each other. It's recommended that you stick with the Strict Equals operator in most cases, as the Equals operator can lead to unintended results.

var ten    = 10,
    number = "10";

console.log( ten == number );      // true
console.log( ten === number );     // false

console.log( 0 == false );         // true
console.log( 0 === false );        // false

console.log( null == undefined) ;  // true
console.log( null === undefined ); // false

# String Operators

Often it is useful to combine strings and variables to create longer strings. Use + when concatenating Strings, and += when appending to existing strings.

var month = "03",
    day   = 24,
    year  = "1992",
    output = "My date of birth is: ";

output += month + "/" + day + "/" + year;

console.log(output); // My date of birth is: 03/24/1992

# Integer parsing

When working with JSON and CSV files, data will be read as a string. If you are reading a list numbers you will later be using in computations, cast the strings to numbers using the + sign.

var string = "50";

console.log(string + 100);  // 50100
console.log(+string + 100); // 150

parseInt() gives you more flexibility, allowing you to specify from which radix you are converting your number to its decimal equivalent.

var string = "50";

string = parseInt(string, 10);
console.log(string + 100);  // 150
var binary = parseInt("110010", 2);
console.log(binary);        // 50 

More info: parseInt(string[, radix])

# Functions

You can write functions in JavaScript like typical functions:

function doSomething(param) {
    return param;
}

console.log( doSomething(10) );  // 10

# Passing parameters in JavaScript

Primitive types are passed in by value. Everything else is passed in by reference. Even when passed in by reference, reassigning the value of the parameter will make the parameter a local variable.

function doSomething(param) {
    param = param.toUpperCase(); // param is now a local variable
    console.log(param);
}
var string = "test";

/* note that string will be passed in by reference */
doSomething(string);             // TEST
console.log(string);             // test

More info: string.toUpperCase()

# Anonymous functions

Functions can also be assigned to variables as anonymous functions. Unlike the typical functions I introdued earlier, these functions must be declared before they are used.

var sayNothing = function() {
    console.log("nothing");
};

typeof(sayNothing);          // function
var method = sayNothing;     // method = function() { console.log("nothing"); };
typeof(method);              // function
method();                    // nothing same as calling sayNothing()

So long as the anonymous function is defined before it’s used, it is functionally equivalent to the following function:

function sayNothing() {
    console.log("nothing");
}

Hoisting

tl;dr The problem is that, whether you realise it or not, javascript invisibly moves all the var declarations to the top of the function scope.

# Arrays, Objects, and Custom Objects

# Arrays

Creating an index-based array in JavaScript is very easy:

var array = [1, 2, 3, 4, 5];

// invoke the .toString() method
console.log(array);             // [1, 2, 3, 4, 5]

You can also create an empty array of a certain size using the Array() constructor:

var array = new Array(500);

More info: Array()

You can access the value of an array value based on their 0-based placement in the array using bracket notation:

var array = [1, 2, 3, 4, 5];

console.log( array[4] );        // 5

Bracket notation also allows you to access properties of objects such that array["foo"] returns the value of the foo property in array.

var array = [];

array[5] = "anything";
array["foo"] = "bar";

// iterate through all the properties
for ( var x in array ) {
    console.log(array[x]);
}

More info: for...in

Although their values are equivalent, the two variables are not equal when compared:

var array1 = [1, 2, 3, 4, 5];
var array2 = [1, 2, 3, 4, 5];

console.log( array1.toString() === array2.toString() ); // true
console.log( array1 == array2 );                        // false
console.log( array1 === array2 );                       // false

This is because arrays are actually objects, and objects are only ever equivalent by comparison when they are referencing the same instance:

var x = [1, 2, 3, 4, 5];
var y = x;

console.log( x == y );  // true
console.log( x === y ); // true

Although string is treated as an object when used as a parameter, it is treated like a primitive type when used in comparison:

var x = "string"; 
var y = "string";

console.log(x == y);  // true
console.log(x === y); // true

I’ve included some of the useful functions in Array at the end of this tutorial, although I recommend you read through the rest of this article before looking at these more complex functions.

# Objects

You can create a single instance of an object using { and }. Objects have properties, which can be set directly on the object. You can access these properties using either bracket notation or dot notation.

var object = {
    // All members are public
    string: "String",
    bool: true,
    num: 5
};
var attribute = "num";

console.log(object.string);     // String
console.log(object["bool"]);    // true

/* You must use bracket notation to access a property with a variable */
console.log(object[attribute]); // 5

More info: Object()

Create an empty object in JavaScript with {} or new Object()?

tl;dr

Objects – Never use new Object(); — it’s klunky and looks silly. Arrays – Always use [] over new Array(); — except when you need to quickly create an “empty” array with a predefined length.

As a dynamically typed language, you can also create properties for objects on the fly

var me = {
    name: "Adam",
    gender: "male"
};
me.funny = true;

for ( var thing in me ) {
    console.log(thing + ": " + me[thing]);
}

/* output would be:
name: Adam
gender: male
funny: true
*/

# Custom Objects

You can also use the function keyword to create constructors. Constructors create custom objects using the new operator. Custom objects are essentially instances of classes, but JavaScript is class-less. Public variables are referenced by setting them as a property of this, which in the context of a constructor, refers to the object being instantiated. Private variables are locally declared using var.

/* This function is the constructor for MyClass */
function MyClass(num, b) {
    //public members
    this.string = "String";
    this.num = num;

    //local (private) members
    var bool = b;
}
var instance = new MyClass(5, false);

console.log(instance.string); // String

# Variable scope and closure

Any variable defined using var is private, and is inaccesible outside of the constructor function itself. You can create privileged methods using this to access and modify these private variables. A privileged method has the same accessibility as a public method.

function account(name, b) {
    this.name = name;
    var balance = b;

    // Privileged members
    this.getBalance = function() { 
        return balance;
    };
    this.transaction = function(amount) {
        balance += amount;
    };
}

var amex = new account("Adam", 1000);
console.log(amex.name);           // Adam
console.log(amex.balance);        // undefined
console.log( amex.getBalance() ); // 1000
amex.transaction(-100);
console.log( amex.getBalance() ); // 900

Functions can also define inner anonymous functions that have a similar function to classes. Although typically variables do not exist outside of the scope of the function they are defined in, any inner function that uses either the parameter or locally defined variables will retain the values. This is the main idea behind closure; variables exist beyond their typical lifecycle.

// The outer function defines a variable called "name"  
var display = function(name) {
    var before = "My name is ";

    return function() {
        return before + name;
    };
};

var print = display("Adam");
typeof(print); // function
console.log( print() );       // My name is Adam

# Functions in objects

Classes can also have functions, and can even take functions as parameters:

function MyClass(param, method) {
    this.method = method;
    this.other = function() {
        console.log(param);
    };
}

var instance = new MyClass("test", function() { console.log("anything"); });

console.log(instance.method); // function() { console.log("anything"); });
instance.method();            // anything
instance.other();             // test

Private members can have public getters and setters:

function account(initial) {
    var balance = initial;

    this.transaction = function(amount) {
        balance += amount;
    };
    this.getBalance = function() {
        return balance;
    };
}

Or you can write them both as a single method using the arguments object:

function Circle(r) {
    var radius = r;

    this.radius = function(r) {
        if ( arguments.length === 0 ) {
            return radius; 
        }
        radius = r;
    }
}

var shape = new Circle(5);
console.log( shape.radius() ); // 5
shape.radius(10);
console.log( shape.radius() ); // 10

More info: arguments

You cannot overload functions in JavaScript; this will merely overwrite them. Fortunately, JavaScript functions are variadic. The arguments object gives you full access to all variables passed into the function:

function add() {
    var sum = 0;
    if(!arguments.length) return sum;
    for ( var i = 0; i < arguments.length; i++ ) {
        sum += arguments[i];
    }
    return sum;
}

console.log( add() );        // 0
console.log( add(1) );       // 1
console.log( add(1, 2) );    // 3
console.log( add(1, 2, 3) ); // 6

More info: for

# Function chaining

Function chaining is also very popular in JavaScript. The idea is that when modifying an object, rather than returning void, you return the modified object. This way, you can make multiple modifications on one line.

function Rectangle(w, h) {
    var width = w,
        height = h;

    this.width = function(w) {
        if(!arguments.length) return width;
        width = w;
        return this;
    };
    this.height = function(h) {
        if(!arguments.length) return height;
        height = h;
        return this;
    };
    this.getArea = function() {
        console.log(width * height);
    };
}

/* Without using function chaining */
var shape1 = new Rectangle(10, 10);
shape1.getArea(); // 100
shape1.width(5);
shape1.height(5);
shape1.getArea(); // 25

/* Using function chaining */
var shape2 = new Rectangle(10, 10);
shape2.getArea(); // 100
shape2.width(5).height(5).getArea(); // 25

# Prototype based programming

Constructors create instances of classes as objects using the new keyword. Every time the constructor is called with the new keyword, memory is allocated for everything in the object. JavaScript provides a way for instances of the same class to share common methods. Using prototype, you can still access public methods and variables using this.

function Circle(r) {
    this.r = r;
}

// {ClassName}.prototype allows you to define public functions
// which only have access to public members of the class
Circle.prototype.radius = function(r) {
    if(!arguments.length) return this.r;
    this.r = r;
    return this;
};

var shape = new Circle(10);
console.log( shape.radius() ); // 10
shape.radius(4);
console.log(shape.radius());   // 4

Anything defined using prototype will be overridden if it is re-defined in the constructor or on the instance itself. Remember that the only place where private variables are accessible is in the constructor.

function Circle(rad) {
    var r = rad;

    this.radius = function(rad) {
        if(!arguments.length) return r;
        r = rad;
    };
}

Circle.prototype.area = function() {
    return this.radius() * this.radius() * Math.PI;
}

var c = new Circle(10);
console.log( c.area() ); // 314.159265358979

# Static variables

Static variables are also possible.

var Person = function(name) {
    this.name = name;
    ++Person.population;
};
Person.population = 0;

var me = new Person("Adam");
console.log("Name: " + me.name);                 // Name: Adam
console.log("Population: " + Person.population); // Population: 1

# Inheritance

Prototype based programming also supports inheritance. In order to understand how inheritance works, we must look more in depth at how JavaScript handles prototypes.

# The prototype

Every object has a prototype. Prototypes are objects which contain a set of properties that are passed down to the object they are assigned to, and can be thought of as a parent class. The default prototype for all objects is Object(). An object’s prototype is not publicly accessible, but can be accessed using Object.getPrototypeOf(object).

var a = {};

Object.getPrototypeOf(a); // Object
a.prototype;              // undefined

More info: Object.getPrototypeOf(object)

Constructors (and functions), on the other hand, have explicit prototype properties. The prototype property is the object which is assigned to the prototype of each instance.

function Person(name) {
    this.name = name;
}

var me = new Person("Adam");
me instanceof Person;      // true
me instanceof Object;      // true
Object.getPrototypeOf(me); // Person

// Note that the prototype of any object created using a constructor
// is set to the prototype property of its constructor.
console.log( Person.prototype === Object.getPrototypeOf(me) ); // true

More info: objectinstanceofconstructor

# Prototype chain

By setting the prototype property of a constructor to a different object, you are creating what is called the prototype chain. Instead of directly inheriting from Object(), you inherit from this parent object first, and then inherit whatever that object’s prototype is. Inheritance sometimes requires that you call the parent constructor, and this is done using {Parent}.call(). By passing the instance of Pet, this, into call(), all properties that are assigned using this in Animal are directly assigned to the instance of Pet. By setting the prototype of Pet to new Animal(), Pet inherits the properties assigned to Animal.prototype.

var Animal = function(name) {
    this.name = name;
};
Animal.prototype.breathe = function() {
    console.log(this.name + " took a breath");
};

var Pet = function(name, owner) {
    Animal.call(this, name);
    this.owner = owner;

    console.log("Name is " + this.name);
};

/* Pet inherits the properties defined in Animal.prototype */
Pet.prototype = new Animal();

var dog = new Pet("Rover", "Adam"); // Name is Rover

console.log(dog instanceof Pet);    // true
console.log(dog instanceof Animal); // true
console.log(dog instanceof Object); // true

console.log(dog.name);              // Rover
console.log(dog.owner);             // Adam
dog.breathe();                      // Rover took a breath

More info: fun.call(thisArg[, arg1[, arg2[, ...]]])

# Accessors and Mutators

When accessing a property, JavaScript will return the top-most value in the prototype chain. Mutations always happen at the top-most level in the prototype chain.

var Person = function(name) {
    this.name = name;
};
Person.prototype.x = 10;
var Student = function(name, major) {
    Person.call(this, name);
    this.major = major;
    this.x = 15;
};
Student.prototype = new Person();

var me = new Student("Adam", "Computer Science");
console.log(me.x); // 15
me.x = 20;         /* same as this.x in constructor */
console.log(me.x); // 20

Additional Resources

# Defining JavaScript as a weakly and dynamically typed language

# Strongly typed and weakly typed languages

A programming language is strongly typed if its variable declaration uses data types. A programming language is weakly typed if variables aren’t declared with a specific data type.

This doesn’t, however, mean that variables don’t have different data types:

typeof 4;                            // number
typeof x;                            // undefined
typeof true;                         // boolean
typeof "String";                     // string
typeof {};                           // object
typeof [] ;                          // object
typeof function() { alert("hi!"); }; // function

More info: typeof

# Static and dynamic typing

A statically typed language requires that, when declaring variables, you define what type the variable is. Once a variable has been bound to a type, you may only assign values of the same type to that variable. JavaScript is a dynamically typed language, in which variables are not bound to any type. The following segment of code is completely valid:

var x = "String";
console.log(x);   // String
x = 5;
console.log(x);   // 5
x = true;
console.log(x);   // true
x = null;
console.log(x);   // null

# Advanced Topics

# Callbacks

A callback is a function that is provided to another function to be called when the other function deems it to be necessary.

function MyFunction(callback) {
    console.log("Did stuff in MyFunction");

    if ( typeof callback === "function" ) {
        callback();
    }
}

function doSomething() {
    console.log("Did something");
}

MyFunction(doSomething);
console.log("Great!");

/* output
Did stuff in MyFunction
Did something
Great!
*/

# Array iteration methods

The following functions are for use on Arrays. The required parameter is a callback function which will be called on every element in the Array with the following parameters:

callback(d, i, array)

  1. d is the current element in the Array (data).
  2. i is the index of the current element in the Array.
  3. array is the array being iterated.

# Array.filter()

When you want to access specific members in an array based on some condition, that’s where filter() comes in. filter() does not directly modify the current Array, but will return a new filtered Array when completed.

var people = [
    {name: "Adam", gender: "male"},
    {name: "Spencer", gender: "male"},
    {name: "Clare", gender: "female"},
    {name: "Joe", gender: "male"}
];

var boys = people.filter(function(d) { return d.gender === "male" });

console.log(people.length); // 4

for ( var i in boys ) {
    console.log(boys[i].name);
}

/* output
Adam
Spencer
Joe
*/

More info: array.filter(callback[, thisObject])

# Array.forEach() and Array.map()

The forEach() and map() functions essentially do the same thing: run the calback for every element in your Array. The only difference is that forEach() will directly modify the Array, and map() will return a new Array, leaving the old one intact.

var people = ["Adam", "Spencer", "Clare", "Joe"];

var names = people.map(function(d, i) { return ( i % 2 === 0 ) ? d.toUpperCase() : d.toLowerCase(); } );
console.log(names); // ["ADAM", "spencer", "CLARE", "joe"]

More info: array.forEach(callback[, thisArg]), array.map(callback[, thisArg])

Closing Remarks

Thank you for reading my tutorial. Please feel free post questions, suggestions, and comments below. I hope that you’ll stick around to read my d3.js tutorial.


Additional Resources

Last Revision: June 25, 2012

This post was written by

Adam Wexler – who has written posts on adamonio.us.
Adam Wexler is 20 years old and is currently studying Computer Science and Business at the University of Southern California. His research with the Computational Behavior Group involves working on data analysis and data visualization techniques using d3.js.

Email  • Google + • Twitter

7 thoughts on “Introduction to JavaScript

  1. I’m a beginner in JS, just wanna say this is a very nice comprehensive tutorial.
    Bookmarked. Gonna read it ASAP. :)

  2. In your Example you use
    var shape = new Circle(5);
    console.log( circle.radius() ); //wrong
    should be
    console.log( shape.radius() ); //ok
    In other
    Person.prototype instanceof Person; // true **wrong
    Person.prototype instanceof Person; // false **ok

    Thanks nice tutorial

  3. Really good tutorial. Although I think you should mention the partial browser support of Array.filter, Array.map and Array.forEach.

  4. Excellent guide !
    Will read that again and again, this is exactly what i needed !

    This tutorial does not require any prior experience in writing JavaScript, but does assume a basic understanding how Object Oriented Programming works, and a familiarity with using Developer Tools

    This post does the job perfectly !

  5. I have an job interview tomorrow for a Javascript developer position. This is a very nice and well written walkthrough. It certainly helped me understand Javascript as someone who works with C#. Thanks Adam! Cheers from Reddit

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>