Elvenware

JavaScriptFunctions

Welcomes to JavaScriptFunctions

Overview

Functions play a central role in the JavaScript language. They are easy to use, but hard to fully understand.

When in doubt, go back to the index.

Functional

JavaScript is sometimes described as having features found in a functional language. It is not a pure functional language, but it shares some features of functional languages.

Though "functional programming" is a technical term with certain specific meanings, for now, we can simply say that JavaScript is a functional language in the sense that functions are the basic building blocks of well written JavaScript code. Functions are first class citizens of JavaScript because they can be:

JavaScript functions can have properties and methods. They rely heavily on callbacks and closures, both of which are are made possible by JavaScript's remarkable implementation of functions.

There is no single way to invoke a function. In fact, they can be invoked in four different ways:

Each of these invocation methods has distinct features, particularly in regard to the this operator.

Functions play a role in JavaScript similar to that played by objects in a language like C# or Java. They are the building blocks of the language.

NOTE: If your mind is full with the wonders of a langauge like C#, there is good reason for your opinion. But consider this: the move to add LINQ to C# was in part an attempt to give C# some of the features that have long been built into JavaScript. Many of these "LINQ like" features of JavaScript derive from the central and powerful role played by JavaScript functions. In other words, it is not always that one language is innately superior to another language, but rather that each has its own virtues.

What are Functions

Functions are unique in that they can be invoked, they can be executed.

Somewhat unexpectedly, functions are like any other value in JavaScript. In particular, functions are objects. In particular, functions are instances of the built-in JavaScript Function object.

Because functions are objects, you can do many of the same things with them that you can do with a string, numberor object. For instance, you can:

Because functions are objects, you can do the same things with them that you can do with any other object. For instance, you can give them properties and methods. Note that functions also have:

We will discuss prototypes in more depth later on in this document. The key point to grasp at this point is simply that all functions automatically get a constructor, which points at themselves, and an empty prototype.

Types of Functions

There are several styles of functions. The simplest:

function fulano() {}  // Simple function

var fulano = function() {}; // Anonymous function assigned to a variable

function Fulano() {} // Function constructor. Capital letter means call it with new.

var myObject = {
   prop: 1,             // Property inside an object
   fulano: function() { } // Function as a method of an object
};

function Fulano() {
  var bar  = function() {}; // function inside a function constructor
  Fulano.prototype.foo = function() {};  // Function on a prototype
}

As explained later, these various ways of invoking a function alter the value of the this keyword inside the function.

Simple Functions

Here is one way to write a JavaScript function:

function Test01() {
    var name = "Test01";
    $("#Test01").html(name);
}

This declaration has the following parts:

Two Ways to Declare Functions

Here is a second way to declare a function. This time we will store an anonymous function in a variable called test01:

var test01 = function() {
   var name = "Test01";
   $("#Test01").html(name);
};

There is little practical difference between assigning a function to a variable as shown here, or the creating functions as shown above. When assigned to a variable, as shown above, the name field of the function object is not filled out. When you declare a function as shown earlier, then the name filed is filled out.

Consider the following program:

var variable00;
var func01 = function() {};
function func02() {}

console.log("variable00: " + variable00);
console.log("func01.name: " + func01.name);
console.log("type of func01.name: " + typeof func01.name);
console.log("func02.name: " + func02.name);

Here is the output:

variable00: undefined
func01.name:
type of func01.name: string
func02.name: func02

Notice that func01 is assigned to a variable, and func02 is a standard function. Hence we see that func01 has no name while func02 has a name.

You can find the source for this example on GitHub:

JsObjects/JavaScript/Syntax/Function01

Arguments and Parameters

A function can be passed parameters and can return a value:

function multiply(a, b) {
    return a * b;
}

This function differs from the first sample in that it takes two parameters, called a and b. Here is a somewhat more verbose version of the same function. This second verison has more descriptive parameters called operandA and operandB:

function multiply(operandA, operandB) {
    return operandA * operandB;
}

Notice that we don't declare the types of the parameters, nor the type of the return value. There is no type checking on these parameters. If we omit a parameter when invoking the function then that parameter will have the value undefined. If we pass in too many parameters when calling a function, then the extra parameters will simply be ignored.

Each function is implicitly passed an object called arguments. Suppose you declare a method that looks like this:

function add() {
}

Suppose further that you call it like this:

add(12, 15);

Even though you did not specify any parameters for the function, you can nevertheless access the arguments that are passed in to it:

function add() {
    if (arguments.length === 2) {
        return arguments[0] + arguments[1];
    } else if (arguments.length === 1) {
        return arguments[0] * 2;
    } else {
        throw('You must pass in either one or two parameters.');
    }
}

Here is a complete example:

function UserException(message) {
   this.message = message;
   this.name = "UserException";
}

function add() {
    if (arguments.length === 2) {
        return arguments[0] + arguments[1];
    } else if (arguments.length === 1) {
        return arguments[0] * 2;
    } else {
        throw new UserException('You must pass in either one or two parameters.');
    }
}


console.log(add(2));
console.log(add(2, 3));
console.log(add());

The source is here:

The this Keyword

The this keyword in JavaScript is often called the function context. If you are used to C# or other object oriented langauges, you may have certain preconceived ideas about the this operator which will prevent you from understanding the role this plays in JavaScript.

The key point to grasp is that the function context changes depending on how you invoke a function. The change occurs not because of the way you declare a function, but because of the way you invoke it. In particular, there are four ways to invoke a JavaScript function:

If you are working in a web browser, and you invoke a simple standalone function, then the this object will usually be the global window object that is part of the browser:

function runMe() { return this; }
var functionContext = runMe();

In the code shown above, functionContext will be the window object.

Consider this code:

    var myObject = {
        runMe: function() {
            return this;
        }
    }

    var functionContext = myObject.runMe();

In the code shown above, functionContext will be myObject.

And finally, let's look at this example:

    function RunMe() {
        console.log(this);
    }

    var functionContext = new RunMe();

In this last example, we are creating a constructor by invoking the new operator. In this case, functionContext is RunMe.

Here are all three cases pulled together in a single program from JsObjects calld ObjectThis:

    function runMe() { return this; }

    var myObject = {
        runMe: function () {
            return this;
        }
    }

    function RunMe() {
        $('#test03').append(this instanceof RunMe);
    }

    $(document).ready(function() {
        "use strict";
        var functionContext = runMe();
        $('#test01').append(functionContext === window);

        var functionContext2 = myObject.runMe();
        $('#test02').append(functionContext2 === myObject);

        var functionContext3 = new RunMe();
        $('#test04').append(functionContext3 instanceof RunMe);   
    });

In strict mode, this is set to undefined rather than the global object when invoking a standalone method without calling new:

function hello01() {
    console.log(this);
}

hello01(); // global object

function hello02() {
    "use strict";
    console.log(this);
}

hello02(); // undefined

Functions and Variables

There is no difference from the callers point of view between these two declarations:

function saveScore() { }
var saveScore = function() {};

One is a function named saveScore and the other is a variable called saveScore that references an anonymous function. You can call them both like this:

saveScore();

The differences is that the first one has a property called name that is set to the value saveScore, while the second has a property called name that is set to an empty string.

NOTE: To see the difference in the name property of the two versions of saveScore, take a look at the Functions01 example from JsObjects/JavaScript/Syntax. Note also that declaration with an anonymous function ends with a semicolon and the other does not.

If you are setting up a callback, then you just pass in a variable which is the name of a function:

$("#Button01").click(myButtonClickHandler);

In this case, we don't call the function, that is we don't write this:

$("#Button01").click(myButtonClickHandler());

We just pass in its name, as shown in the first of the two examples shown above.

All this is a bit confusing to new comers because they are not used to languages where functions are first class members of the language. A JavaScript function has all the power of any other object or variable. That's why the following are the same:

function saveScore() { }
var saveScore = function() {};

It just doesn't matter whether you are calling a function or a variable that points at a function. Both are objects, and both are treated the same.

Functions and Objects

Each function that you declare in JavaScript is an object. When you look at the following code, you might therefore be forgiven for supposing that name is a field of Test01, and that a call to print that name would work. In fact, name is a private field of the object, and therefore cannot be seen by an instance of Test01. The description property, shown below, is a public member of Test01, and it will be accessible from an instance of the object.

var Test01 = function()
{
   var name = "Test01";
}

Test01.prototype.description="This is a test object";

var Test02 = function()
{
    var test01 = new Test01();
    $("#Description01").html(test01.description);
    $("#Name01").html(test01.name);
}

When Test02 is called, the code shown above prints out the string "This is a test object" but it does not print out the words "Test01." That is because the property description is visible to an instance of Test01, but the field name is unknown.

To make name a public field of the object, write code that qualifies the instance of nameStrwith the keyword this:

var Test01 = function()
{
    this.nameStr = "Test01";
}

Test01.prototype.description="This is a test object";

var Test02 = function()
{
    var test01 = new Test01();
    $("#Description01").html(test01.description);
    $("#Name01").html(test01.nameStr);
}

Now the code shown above behaves as expected, and inserts both nameStr and description into the appropriate tags in our HTML.

Like Extensions methods in C#, you can use Prototype to change the way existing classes work. In the following example, we will add a method called Decorate to the built-in JavaScript String class:

String.prototype.decorate = function() {
 return "-***-" + this + "-***-";
}

Now when you create a string, you can call its decorate method:

this.testDecoration = function() {
    var testStr = "All my strings can be decorated";
    $("#testPlain").html(testStr);
    $("#testDecorate").html(testStr.decorate());
}

Click here to try decorating a string.

Strict Mode

General changes:

A few of the Details:

Callbacks: Passing Functions as Parameters

Callbacks are very common in JavaScript. In other languages, they are often considered esoteric, but in JavaScript they happen all the time.

NOTE: Callbacks are the key to understanding asynchronous processing in JavaScript. If we are in a browser and make a call to the server, then we don't know when, or even if, the call will return. As a result, we don't make the call synchronously. That is, we don't wait around for the call to return. Instead, we make the call, and then continue on processing code. When the call returns, we are notified. This is known as an asynchronous call, and in JavaScript we handle these calls with callbacks. Since we make lots of calls to the server in a typical JavaScript program, our ability to understand callbacks becomes key to our ability to understand even basic Web programming.

JavaScript considers functions to be first class citizens of the language. This means that you can easily assign them to variables, and pass them around to other functions. Other languages usually provide support for function pointers of function objects, but the syntax is often awkward or challenging to use. In JavaScript, you can simply treat a function like any other type, such as a Number, String or Boolean.

NOTE: Because functions in JavaScript are so flexible, many consider JavaScript to be a functional programming language. Functional programming is enormously powerful, and also quite different from the type of imperative programming done in Java and C#. Ultimately, the flexibility of JavaScript functions will enable you to write your code in a functional style that is quite different from what you write when using more traditional languages. This is not the place to explore this topic in depth, but you should at least be aware of the power of functions in JavaScript, and the way that they shape our approach to the language. Functional programming is a type of declarative programming.

Here is an example of how to use callbacks in JavaScript:

/**
 * @author Charlie
 */

function hello(func) {
    $("#test02").html("It works! ");
    func();
}

$(document).ready(function() {
  "use strict";


  $("#test01").html("Document Read called");

  hello(function() {
      $("#test03").html("It's a nine!");
  });

});

The complete example is here:

In this example, we pass an anonymous function to the method hello. As you can see, hello takes a single parameter called func:

function hello(func) {

When we call hello we pass in an anonymous function, a bit like this:

    var helloParameter = function() {
          $("#test03").html("It's a nine!");
    }

    hello(helloParameter);

But in JavaScript we get a special dispensation, as it were, and don't even have to declare the variable that points at our function. Instead, we can just pass it in directly as an anonymous function:

    hello(function() {
        $("#test03").html("It's a nine!");
    });

We call the function anonymous because it has no name:

function() {
    $("#test03").html("It's a nine!");
}

Compare the above to a standard function with a name:

    function writeNine() {
        $("#test03").html("It's a nine!");
    }

If callbacks and anonymous functions are unclear, think about them some more. If these subjects are still unclear, get up, take a 1 minute walk, then come back and think about it all again. Download the example and step through it. Come to terms with this syntax. You will never really understand JavaScript until you understand code of this type.

Aside: Do JavaScript programmers dream callbacks? Of course!

Here is another example designed to drive home the points outlined above:

/**
 * @author Charlie
 */

var Converter = (function() {

    // Private variable
    var x = 0;

    // Constructor
    function Converter(initX) {
        x = initX;
    }

    // Private method
    function square(value) {
        return value * value;        
    }

    // Public methods
    Converter.prototype.convert = function(func) {
        var result = square(x);
        return func(result);      
    };

    return Converter;
})();

$(document).ready(function() {"use strict";

    var converter = new Converter(2);

    var feet = converter.convert(function(miles) {
        return miles * 5280;
    });

    var yards = converter.convert(function(miles) {
        return miles * (5280 / 3);
    });

    $("#feet").html(feet);
    $("#yards").html(yards);
});

The source is here:

Calling a JavaScript Function from a Declaration

The following code demonstrates the differences between assigning a method to a variable and assigning the result of a function call to a variable. Notice the extra parentheses at the end of the getNine02. This causes the function to be called at the time of the assignment. This means that getNine02 ends up a being a number, while getNine01 ends up being function object.

In the getNine02 example, the open parenthesis before the word function is syntactical sugar. It does not have any other function other than to tell us that this function is going to be called immediately with the closing set of parentheses. If one is reading a long function, we want to be told up front that it is going to be called immediately. There is no good way to do that, so a convention has been developed of adding parentheses before the word function to serve as a hint that the function will be called immediately.

    /**
     * @author Charlie
     */

    // getNine is assigned a function that returns the number 9
    var getNine01 = function() {
        return 9;
    }

    /*
     * getNine02 is set to the number 9. Notice the
     * the parentheses at the end of the statement.
     * They force the function to be called during the
     * assignment
     */
    var getNine02 = (function() {
        return 9;    
    })();

    $(document).ready(function() {
      "use strict";

      // We call getNine01() because it is a function
      var result01 = getNine01();
      $("#test01").html(result01);

      // Get Nine02 is not a function, but a simple number
      // Hence it is not called. Notice there are no parentheses
      var result02 = getNine02;
      $("#test02").html(result02);
    });

Comparing JavaScript objects and JavaScript functions

Previously in this document, in the section on objects, we declared a simple object that looks like this:

var myObject = {                
    myProperty01: 12,
    myProperty02: 4,
    myFunction01: function() {
        return this.myProperty01 + this.myProperty02;                
    }                
);

We call it like this:

myObject.myFunction01()

This is very nice, but it does not give us the option to create private methods.

Here is what the same object would look like if declared as a function:

function myFunction02() {   
    'use strict';

    var myField01 = 3;
    var myField02 = 2;
    var nestedFunction = function() {
        return myField01 + myField02;  
    };

    return nestedFunction();
}

We call it like this:

myFunction02()

Let's call this the Simple Function pattern. This is very nice, but it does not gives us the option to create public methods. As you can see, if I want to call nestedFunction, I need to call it from inside of myFunction02. This is less than optimal in some cases.

Here is a third technique that uses the prototype function syntax, and gives us public methods, but no useful private methods:

var MyFunction03 = function() {
    'use strict';       
};

MyFunction03.prototype.field01 = 2;
MyFunction03.prototype.field02 = 4;
MyFunction03.prototype.nestedFunction = function() {
    'use strict';    
    return this.field01 + this.field02;    
};

We call it like this:

var myFunction03 = new MyFunction03();
myFunction03.nestedFunction();

This is very nice, but it does not give us private methods. Note also, that it forces us to call new when we create the object. If we don't call new, then nestedFunction will not be visible when we try to use the object. In other words, our public method won't be truly public.

And here finally, is a fourth way of writing the same object. We call this the module pattern. It provides both public methods and private methdos, private fields, and it gives us a constructor for initializing the fields. It's syntax is more verbose, but it gives us everything we need. Also, the syntax, though a bit verbose, is similar to the class declarations in other curley brace languages such as C#.

var MyFunction04 = (function() {
    'use strict';

    var field01 = 0,
    field02 = 0;

    function MyFunction04(initField01, initField02) {
        field01 = initField01;
        field02 = initField02;
    }

    MyFunction04.prototype.nestedFunction = function() {
        return field01 + field02;
    };    

    return MyFunction04;
}());

We call it like this:

var myFunction04 = new MyFunction04(1, 2);
myFunction04.nestedFunction();

This is the best solution.

Now go back and look at the original object pattern. Compare it to the one we have created. Notice that they are two different ways of saying the same thing, only the module pattern is more flexible, and more powerful.

Get the Source:

Properties and Inheritance

Inheritance is done most often through the prototype property. Declare a base object:

var BaseObject = (function() {
    'use strict';

    function BaseObject() {
    }

    BaseObject.prototype.firstName = "Qux";

    return BaseObject;
}());

Now define the child object:

var ChildObject = (function() {
    'use strict';

    function ChildObject() {
    }

    ChildObject.prototype = new BaseObject();

    ChildObject.prototype.lastName = "Garply";

    return ChildObject;
}());

The key line is this:

ChildObject.prototype = new BaseObject();

This means that the child will inherit all the properties that are part of the parents prototype. BaseObject, in its turn, automatically inherits all the properties from the built in Object. That means that ChildObject inherits them also.

Now test the code:

var childObject = new ChildObject();
console.log(childObject.firstName);
console.log(childObject.lastName);

As you can see, the child inherits the fistName property from the parent. The working example is here.

Notice that these objects use PascalCase, that is, the initial letter in their name is a Capital. Like this: ChildObject. Not camelCase like this: childObject.

When we use Pascal case for the first letter of an object, we are saying that must be called with new:

var childObject = new ChildObject();

If we want to use the protype property, then we must instantiate the object with new. In other words, prototypal inheritance in JavaScript only works with constructor objects. That is, it only works with objects instantiated with new.

This and That

One of the real weak points in JavaScript is the this keyword. It is designed to allow an object to have access to its own properties and methods. That is common enough. The catch, however, is that this does not always point at what you think it should point at. In particular, in callbacks and the special case of callbacks called event handlers, the this keyword typically points at the object that made the call, or at the global window object. To get around this problem, and to allow an object to have access to itself when in a callback, we do this:

var MyObject = function() {
  var that;
  var foo;

  function MyConstructor() {
     that = this;
  }

  function MyCallback() {
    that.foo = 'baz';
  }
}

This is hard to grasp at first mostly because it does not seem possible that JavaScript should have such a serious flaw in the language. If MyCallBack is part of MyObject then inside of MyCallback this ought to point to MyObject. But this is not necessarily the case, and as a result, we do the craziness with the that variable.

In general, the recommendation is not to use this outside of the constructor. Every place else, it is a danger to itself and others. We spend a lot of time learning how to write code that has no use for either this or that. But sometimes, we have no choice, and use that.

Here is another way to look at the same problem. Private methods and some callbacks cannot always properly access the this property that belongs to the object of which they are members. As a result, we must develop a work around. To solve the problem we typically declare this as that.

function MyFunc() {

    var that = this;
    this.data = 3;

    function privateFunc() {
        console.log(that.data);
    }

    function myEvenHandler(event) {
        console.log(that.data);
    }
}

Please understand that this is just a convention. But it is a common convention. An experienced JavaScript developer who sees that in your code expects it to be pointing to the this property for the enclosing object.