Archive

Archive for the ‘Javascript’ Category

Overloading Functions in Javascript

November 9th, 2013

Javascript does not support the kind of function overloading you find in languages such as C#. For example in C# you can define two version of a function:

// Double a value.
int DoubleAValue(int Value)
{
...

and

// Double a value, but let the user choose only to double
// if the value is greater than 10.
int DoubleAValue(int Value, bool IfGreaterThan10)
{

You can’t do this kind of overloading in Javascript, but a similar capability can be implemented by exploiting the fact that Javascript doesn’t force callers to specify values for all arguments to a function.

So to implement a kind of overloading, you could write your function in Javascript as:

function DoubleAValue(Value, IfGreaterThan10)
{
...

and callers could decide to call the function with or without the second argument:

var Result = DoubleAValue(10);

and

var Result = DoubleAValue(x, true);

To support the optional argument though, the coder has to implement the function to allow for the second argument not to be specified. There is no way to give a default value to the second argument so the function has to check if the argument is present when called. To do this the function can check whether the argument is undefined …

function DoubleAValue(Value, IfGreaterThan10)
{
    var LocalIfGreaterThan10 = true;

    if (typeof IfGreaterThan10 != 'undefined') {
        // The argument is present on this call. Take the value from the argument.
        LocalIfGreaterThan10 = IfGreaterThan10;
    }

    if (Value <= 10 || LocalIfGreaterThan10) {
        Value = Value * 2;
    }

    return Value;
}

For more Javascript help and tips, see: http://www.sliqtools.co.uk/blog/javascript/writing-javascript-objects-and-adding-element-event-handlers/

Writing Javascript Objects and Adding Element Event Handlers

October 19th, 2013

Having developed code in C# and C++ for a number of years, I’ve recently begun to write web software using Javascript. Working out how classes and objects work has been a little confusing and it took a few hours for me to work out how to do things correctly.

In C# and C++ classes and objects work in a similar fashion – you define a class that contains member properties and methods and when you instantiate the class to create an object the methods in the class “belong” to the object, i.e. they can call other methods in the class knowing that the called methods will operate on the same instance members as the caller.

In Javascript, classes are achieved by exploiting the fact that everything is an object including functions. Essentially, in Javascript, a class is created by adding properties and methods to a function object. The following sections show examples of how to do things like define a class, construct an object, define properties and methods.

Simple Javascript Class with Constructor and Properties

Here is a simple Javascript class with a couple of property definitions:

function NumericTextBox(element) {
    // Record the allowable min and max.
    //
    this.Min = 0;
    this.Max = 1000000;
}

The above example defines a NumericTextBox class that accepts an element object in its constructor. The class also defines a Min and a Max property and gives them default values. An object can then be instantiated and its properties set as follows:

var MyObj = new NumericTextBox($('#editfield'));
MyObj.Min = 12;
MyObj.Max = 15;

Note the use of the this keyword to define the properties inside the NumericTextBox constructor. The this points to the object being created by running the constructor, so executing this.Min defines a property Min in the object.

Adding methods to the Javascript Class

Adding a method to the class is done using the prototype keyword, e.g. to add a SetMin method to the NumericTextBox class, do:

NumericTextBox.prototype.SetMin = function (NewMin) {
    this.Min = NewMin;
}

Note the use of the keyword this again (this.Min) when setting the value of a property on the object. this needs to be used to reference the object on which the SetMin method has been called. In languages like C# and C++ there would be no need to insert a this. reference but in Javascript there is.

Adding an Event Handler to the Element Passed to the Javascript Constructor

If we want to add an event handler to the element (JQuery object in this example) passed to the constructor of our class, we have to make sure that when the event is called it executes in the context of our object. For example:

function NumericTextBox(element) {
    this.Min = 0;
    this.Max = 1000000;

    var self = this;

    element.on('keyup', function (ev) {
        self.ReFormatText(ev.target);
    })
}

NumericTextBox.prototype.ReFormatText = function (element) {
}

Note that the keyup event handler calls the class member ReFormatText. However, when the event handler runs, it needs to call the ReFormatText method in the context of the correct object. Unfortunately, due to Javascript scoping rules, if we wrote:

this.ReFormatText(ev.target)

the this keyword would call the method in the wrong context. The method would be called in the context of the event handler function, not in the context of our example object. To get the method called in the correct context, we use the self variable instead, having set the value of self to the correct object context before we defined the event handler.

Calling other Methods in the Same Javascript Object

When one class method calls another in the same class, we need to use the this keyword again so that the called method runs in the correct context and references the correct object’s properties:

NumericTextBox.prototype.SetMin = function (NewMin) {
    this.Min = NewMin;
    this.EnsureMaxGreaterThanMin();
}

There are other ways of defining classes in Javascript but the above techniques allowed me to do everything I needed in a simple class I was developing. I was surprised at how different class definitions were in Javascript compared to C++ or C# but having worked out how to make sure the correct object context was being used in methods, I managed to do everything I needed.