Functions
Functions are the fundamental modular unit of JavaScript, you use them for code reuse, information hiding and composition.
Functions in JavaScript are objects, collections of key/value pairs with a link to a prototype Function.prototype liked to Object.Prototype and a prototype property. Every function also gets two additional hidden properties: its context and the code that implements the function's behaviour.
Defining Functions
- Function Declarations
A Function Declaration defines a named function variable without requiring variable assignment.
function square(number) {
return number * number;
}
This type of function declaration get hoisted, pushed to the top.
foo() //Hoisted
function foo() {
console.log('hoisted')
}
- Function Expressions
Functions can also be created by a Function Expression, these functions can be anonymous.
var square = function(number) { return number * number }
var x = square(4) // x gets the value 16
These type of functions are convenient when passing a function as an argument to another function.
They don't get hoisted, so the code below will throw an error.
foo() //TypeError: foo is not a function
var foo = function foo() {
console.log('not hoisted')
}
Function Invocation
In addition to the declared parameters every function receives two additional parameters : this and arguments. The this parameter will be determined by the invocation pattern.
There are 4 different invocation patterns :
- Method Invocation.
- Function Invocation.
- Apply Pattern.
Constructor Pattern.
Method Invocation
When a function is stored as a property on a object we call it method. When the method is invoked, this is bound to that object.
var myObject = { value: 0,
increment: function (inc) {
this.value += typeof inc === 'number' ? inc : 1; }
};
myObject.increment();
document.writeln(myObject.value); // 1
- Function Invocation
When a function is not the property of an object, then it is invoked as a function:
var sum = add(3, 4); // sum is 7
When a function is invoked with this pattern, this is bound to the global object.
- Constructor Invocation
If a function is invoked with the new prefix, then a new object will be created with a hidden link to the value of the function’s prototype member, and this will be bound to that new object.
// Create a constructor function called Quo. // It makes an object with a status property.
var Quo = function (string) { this.status = string; };
// Give all instances of Quo a public method
// called get_status.
Quo.prototype.get_status = function () {
return this.status;
};
// Make an instance of Quo.
var myQuo = new Quo("confused");
document.writeln(myQuo.get_status()); // confused
- Apply Invocation
// Make an array of 2 numbers and add them.
var array = [3, 4];
var sum = add.apply(null, array); // sum is 7
// Make an object with a status member.
var statusObject = {
status: 'A-OK'
};
// statusObject does not inherit from Quo.prototype,
// but we can invoke the get_status method on
// statusObject even though statusObject does not have
// a get_status method.
var status = Quo.prototype.get_status.apply(statusObject); // status is 'A-OK'
Arguments
When a function is invoked we will have an arguments array-like object parameter available. It gives the function access to all of the arguments that were supplied with the invocation, including excess arguments that were not assigned to parameters.
Return
A function always returns a value. If the return value is not specified, then undefined is returned. If the function was invoked with the new prefix and the return value is not an object, then this (the new object) is returned instead.
Scope
JavaScript does have function scope. That means that the parameters and variables defined in a function are not visible outside of the function, and that a variable defined anywhere within a function is visible everywhere within the function.
Closures
The context of an inner function includes the scope of the outer function (gets access to the parameters and variables) with the exception of this and arguments.
The inner function enjoys that context even after the parent function have returned.
var foo = (function foo() {
var num = 5;
return {
bar : function() {
console.log(num);
}
}
})()
var foobar = foo.bar; //still has access to num;
console.log(foobar.num); //Can't access (undefined), its a way to make fields private in JavaScript
foobar(); //Prints 5