From PHP to JavaScript: functions

For PHP developers, JavaScript can be either a mystery or a nightmare, depending on the personal experience of each developer. There are some false myths concerning JavaScript that I'd like to discuss with you, providing some useful information to guide you from PHP to JavaScript. First and foremost, JavaScript is a client-side language. It totally depends on browser support and user choices. This is the first and most important thing you have to understand. All the problems that you may encounter with JavaScript depend on this. This post is an introduction to JavaScript functions.

Functions are objects

In JavaScript, functions are first-class objects. They can be either used in the traditional, procedural way (exactly as you use them in PHP) or in an object-oriented way, thus becoming object constructors:

// Procedural

function sum(a, b) {
  return a + b;
}

alert(sum(1, 2)); // shows 3

// Object-oriented

function Sum(a, b) {
  this.a = a;
  this.b = b;
  this.sum = function() {
    return this.a + this.b;
  };
}

var mySum = new Sum(1, 2);
alert(mySum.sum();) // shows 3

Already confused? I know exactly how you feel. This is the way I felt when I switched from C++ to JavaScript: confused. But if we past the initial confusion, we'll probably see that in this way of handling functions there's also an enormous potential. For example, in JavaScript there are two ways to handle default function parameters: variables and objects. Here's the variable-based way:

function toHTML(element, attributes, content) {

  element = element || 'div';
  attributes = attributes || '';
  content = content || '';
  
  return '<' + element + ' ' + attributes + '>' 
  + content + '</' + element + '>';
}

element.innerHTML = toHTML('p', 'id="test"', 'Test');

In PHP, default parameters must be declared in the function definition. In JavaScript, they can be declared in the function body. However, many JavaScript developers prefer to use object literals, because they make sure that the correct order of parameters is honored:

function toHTML(options) {

  options = options || {};
  options.element = options.element || 'div';
  options.attributes = options.attributes || '';
  options.content = options.content || '';
  
  return '<' + options.element + ' ' 
  + options.attributes + '>' + options.content + 
  '</' + options.element + '>';

}

element.innerHTML = toHTML({element: 'p', attributes: 'id="test"', content: 'Test});

You can check if the parameters passed to the functions are of the correct type using the typeof operator:

if(typeof options.element !== 'string') {
  throw new Error('element must be a string.');
  return;
}

Another interesting feature of JavaScript functions is that they can be anonymous, that is, without a function name:


setTimeout(function() {

  alert('One!');

}, 1000);

They can also be attached to a page element as inline functions:


window.onload = function() {

  alert('Window loaded!');

};

Variables and function scope

In JavaScript, a variable declared inside a function is not accessible from outside the function where's been declared. On the contrary, a variable defined outside a function can be accessed by that function. In PHP, to accomplish this task you have to use the global keyword. In JavaScript, this is not required:

var a = 'Test';

function merge(b) {

  return b + ' ' + a;
  
}


alert(merge('ok')); // shows 'Test ok'

You should avoid global variables whenever it's possible, because this is considered a bad practice from a namespacing perspective.

Self-referencing functions

JavaScript stores a self-reference in the arguments.callee property attached to each function. Using this property, you can actually create self-referencing functions:

setTimeout(function() {
  // function created
  
  alert('One!');
  
  setTimeout(arguments.callee, 1000); // reference to the function
}, 1000);

However, this property has been deprecated in the strict version of ECMAScript 5.

Further reading

JavaScript functions by Peter-Paul Koch

Leave a Reply

Note: Only a member of this blog may post a comment.