JavaScript Tips, Tricks and Specialities

The purpose if this page is to collect a list of interesting aspects and sidenotes about developing with JavaScript.

arguments

Even withouth declaring a set number of parameters when declaring a function, you can still call a function with several arguments passed to it. Those arguments will then be available within that function as an array-like object called arguments. It is similar to an array, but lacks usual array properties, except length. Example:

<script type="text/javascript">
function someFunction() {
    console.log(arguments); // ["red", [1, 2, 3], Object random=test]
}

// calling the function with several params
someFunction("red", [ 1, 2, 3 ], { "random" : "test" });
</script>

apply

Normall, when you use the this keyword in a function, this refers to the current object in which scope the function is being executed. With apply, you are able to pass an object into given function which will then become the scope of the function, i.e. can be referenced using this. Example:

<ul>
    <li><a href="http://news.bbc.co.uk/">News on BBC website</a></li>
    <li><a href="http://nytimes.com/">Frontpage of The New York Times</a></li>
    <li><a href="http://www.guardian.co.uk/">Guardian Unlimited</a></li>
</ul>

<script type="text/javascript">
function onClickHandler(e) {
    if (e.type === 'click') {
        // when called upon click on an anchor,
        // this refers to anchor object
        console.log("onclick:");
        console.log(this); // anchor object
        console.log(e); // onclick event object
        console.log(arguments); // object (array-like) containing of 1 item, the onclick event

    } else {
        console.log("onmouseover:");

        console.log(this); // testObject
        console.log(e); // 1
        console.log(arguments); // array containing [ 1, 2, 3 ]
    }
    return false;
}

TestExample = {};

TestExample.init = function() {
    var anchors = document.getElementsByTagName("a");

    var testObject = {
        "random" : "Yahoo! Answers"
    };

    for (var i = 0, len = anchors.length; i < len; i++) {
        anchors[i].onclick = onClickHandler;
        anchors[i].onmouseover = function () {
            var arguments = [ 1, 2, 3 ];
            onClickHandler.apply(testObject, arguments);
        }
    }
}();
</script>

Function definition

When I learned about he Module Pattern after I joined Yahoo! in 2007, I was kinda surprised by constructs like this:

var someFunction = function () {
    ...
}

What happens here—beginning on the right hand side of the equal sign—is that an anonymous function gets defined and then gets stored in the variable ‘someFunction’. This is significantly different to this:

function someFunction() {
    ...
}

Both declarations achieve the same, you can call someFunction() within your code and it will do the same. However, it is essential to know when you are, in fact, able to call it.

In the second example, we are creating a new function which is available immediately once the JavaScript parser has finished parsing the code. In the first example, that (anonymous) function becomes available when that piece of code gets executed for the first time, not before. The example below should make it clearer:

<script type="text/javascript">
// someFunction is already available, so the following works
console.log(someFunction); // someFunction()

// calling the function
someFunction(); // someFunction

// we have not reached the myVariable part during program
// execution, so the following does not work
// myVariable(); // myVariable is not a function

function someFunction() {
    console.log("someFunction");
}

var myVariable = function () {
    console.log("my other function");
}

// anonymous function is now available, stored in someFunction2
myVariable(); // my other function
</script>

this keyword

The this keyword normally refers to the object in which scope the current function is being executed. When using Singletons or the Module Pattern it is essential to know how to use the keyword and what it refers to in which instance.

Singleton

Here is a simple Singleton example:

var testObject1 = {
    testProp: "something",

    run: function () {
        console.log(this); // this = object (the testObject1, to be specific)

        console.log(this.testProp); // something
        console.log(testObject1.testProp); // something

        console.log(testProp) // testProp is not defined
    }
};
testObject1.run();
  • console.log(this): this refers to the current object, which is testObject1 in this case, the singleton
  • console.log(this.testProp): testObject1 has a property testProp, so this just prints out the value of that property
  • console.log(testObject1.testProp): Same as above, but now we are referencing the object by its actual name instead of using the keyword
  • console.log(testProp): There is no variable testProp defined in the global namespace, so this returns ‘testProp is not defined’

Module Pattern

var testModule = function () {
    var testModuleProp = function () {
        console.log(this);  // is reference to window object
        console.log(init); // function()
    }

    var init = function () {
        console.log(this); // this = object, that holds init function (and gets returned by return {})
        console.log(testModuleProp); // function()
        testModuleProp();
    }

  return {
    init: init
  }
}();

testModule.init();

Inside the init function, this refers to the object that gets returned by the function and holds the publicly available functions. Inside the module, i.e. inside the function, you can reference other functions by just using the function name, as you would do in any other function in JavaScript. No keyword or anything required to do this.

In testModuleProp, this refers to the window object, because this function is not part of the object being returned. It is a private method. Still you can refer to any other function within the module using the function name.

Arrays vs. Objects

Counting items/properties

The following example shows how items in arrays and properties in objects can be counted.

// create an object
var testobj = {};

// create several testobjects
var mapobject1 = {
    lat: '2422423432',
    lon: '324234234'
};

var mapobject2 = {
    lat: '2422423432',
    lon: '324234234'
};

var mapobject3 = {
    lat: '2422423432',
    lon: '324234234'
};

var mapobject4 = {
    lat: '2422423432',
    lon: '324234234'
};

// assign array, containing testobjects to property of first object
testobj.something = [mapobject1,mapobject2,mapobject3,mapobject4];

// count the number of properties in the object
// only counts immediate object properties, not the ones inherited in the prototype chain
// Warning: only works in FF, not in IE or Opera
console.log(mapobject1.__count__); // 2

console.log(typeof(testobj.something)); // object

// counting the items in array
console.log(testobj.something.length); // 4

Defining Variables and checking their state

Following examples show what happens if variables are not defined and how their state gets evaluated within JavaScript.

// Example 1
var testVar1;

console.log(testVar1); // undefined, meaning testVar1 has no value assigned to it as in testVar1 = 'something'

console.log(typeof testVar1); // 'undefined'

if (!testVar1) { // testVar1 gets evaluated to FALSE
    console.log('This is Example 1');
}

// Example 2
var testVar2 = 0;

console.log(testVar2); // 0

if (!testVar2) { // testVar2 gets evaluated to FALSE
    console.log('This is Example 2');
}

// Example 3
var testVar3 = ''; 

console.log(testVar3); // empty string

if (!testVar3) { // testVar3 gets evaluated to FALSE
    console.log('This is Example 3');
}

// Example 4
var testVar4 = []; 

console.log(testVar4); // empty array

if (testVar4) { // testVar4 gets evaluated to TRUE
    console.log('This is Example 4');
}

// Example 5
// console.log(testVar5.test); // causes runtime error 'testVar5 is not defined'

if (typeof testVar5 == 'undefined') { // need to check it using typeof
    console.log('This is Example 5');
}

// Example 6
var testVar6 = {};

console.log(testVar6); // Object

console.log(typeof testVar6); // object

if (testVar6) { // testVar6 gets evaluated to TRUE
    console.log('This is Example 6a');
}

if (!testVar6.randomProp) { // testVar6.randomProp gets evaluated to FALSE
    console.log('This is Example 6b');
}

Switch to our mobile site