JavaScript functions are defined with the function keyword.
You can use a function declaration or a function expression.
Earlier in this tutorial, you learned that functions are declared with the following syntax:
function functionName(parameters) {
code to be executed
}
Declared functions are not executed immediately. They are "saved for later use", and will be executed later, when they are invoked (called upon).
function myFunction(a, b) {
return a * b;
}
Semicolons are used to separate executable JavaScript statements. |
A JavaScript function can also be defined using an expression.
A function expression can be stored in a variable:
var x = function (a, b) {return a * b};
After a function expression has been stored in a variable, the variable can be used as a function:
var x = function (a, b) {return a * b};
var z = x(4, 3);
The function above is actually an anonymous function (a function without a name).
Functions stored in variables, do not need function names. They are always invoked (called) using the variable name.
The function above ends with a semicolon because it is a part of an executable statement. |
As you have seen in the previous examples, JavaScript functions are defined with the function keyword.
Functions can also be defined with a built-in JavaScript function constructor called Function().
var myFunction = new Function("a", "b", "return a * b");
var x = myFunction(4, 3);
You actually don't have to use the function constructor. The example above is the same as writing:
var myFunction = function (a, b) {return a * b}
var x = myFunction(4, 3);
Most of the time, you should avoid using the new keyword in JavaScript. |
Earlier in this tutorial, you learned about "hoisting".
Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope.
Hoisting applies to variable declarations and to function declarations.
Because of this, JavaScript functions can be called before they are declared:
myFunction(5);
function myFunction(y) {
return y * y;
}
Functions defined using an expression are not hoisted.
Function expressions can be made "self-invoking".
A self-invoking expression is invoked (started) automatically, without being called.
Function expressions will execute automatically if the expression is followed by ().
You cannot self-invoke a function declaration.
You have to add parentheses around the function to indicate that it is a function expression:
(function () {
var x = "Hello!!"; // I will invoke myself
})();
The function above is actually an anonymous self-invoking function (function without name).
JavaScript functions can be used as values:
function myFunction(a, b) {
return a * b;
}
var x = myFunction(4, 3);
JavaScript functions can be used in expressions:
function myFunction(a, b) {
return a * b;
}
var x = myFunction(4, 3) * 2;
The typeof operator in JavaScript returns "function" for functions.
But, JavaScript functions can best be described as objects.
JavaScript functions have both properties and methods.
The arguments.length property returns the number of arguments received when the function was invoked:
function myFunction(a, b) {
return arguments.length;
}
The toString() method returns the function as a string:
function myFunction(a, b) {
return a * b;
}
var txt = myFunction.toString();
A function defined as the property of an object, is called a method to the object. |
A JavaScript function does not perform any checking on parameter values (arguments).
Earlier in this tutorial, you learned that functions can have parameters:
functionName(parameter1, parameter2, parameter3) {
code to be executed
}
Function parameters are the names listed in the function definition.
Function arguments are the real values passed to (and received by) the function.
JavaScript function definitions do not specify data types for parameters.
JavaScript functions do not perform type checking on the passed arguments.
JavaScript functions do not check the number of arguments received.
If a function is called with missing arguments (less than declared), the missing values are set to: undefined
Sometimes this is acceptable, but sometimes it is better to assign a default value to the parameter:
function myFunction(x, y) {
if (y === undefined) {
y = 0;
}
}
Or, even simpler:
function myFunction(x, y) {
y = y || 0;
}
If y is defined, y || returns y, because y is true, otherwise it returns 0, because undefined is false. |
If a function is called with too many arguments (more than declared), these arguments cannot be referred, because they don't have a name. They can only be reached in the arguments object.
JavaScript functions have a built-in object called the arguments object.
The argument object contains an array of the arguments used when the function was called (invoked).
This way you can simply use a function to find (for instance) the highest value in a list of numbers:
x = findMax(1, 123, 500, 115, 44, 88);
function findMax() {
var i, max = 0;
for (i = 0; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
Or create a function to summarize all input values:
x = sumAll(1, 123, 500, 115, 44, 88);
function sumAll() {
var i, sum = 0;
for (i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
return sum;
}
The parameters, in a function call, are the function's arguments.
JavaScript arguments are passed by value: The function only gets to know the values, not the argument's locations.
If a function changes an argument's value, it does not change the parameter's original value.
Changes to arguments are not visible (reflected) outside the function.
In JavaScript, object references are values.
Because of this, it looks like objects are passed by reference:
If a function changes an object property, it changes the original value.
Changes to object properties are visible (reflected) outside the function.
JavaScript functions can be invoked in 4 different ways.
Each method differs in how this is initialized.
In JavaScript, the thing called this, is the object that "owns" the current code.
The value of this, when used in a function, is the object that "owns" the function.
Note that this is not a variable. It is a keyword. You cannot change the value of this. |
You have already learned that the code inside a JavaScript function will execute when "something" invokes it.
The code in a function is not executed when the function is defined. It is executed when the function is invoked.
Some people use the term "call a function" instead of "invoke a function".
It is also quite common to say "call upon a function", "start a function", or "execute a function".
In this tutorial, we will use invoke, because a JavaScript function can be invoked without being called.
function myFunction(a, b) {
return a * b;
}
myFunction(10, 2); // myFunction(10, 2) will return 20
The function above does not belong to any object. But in JavaScript there is always a default global object.
In HTML the default global object is the HTML page itself, so the function above "belongs" to the HTML page.
In a browser the page object is the browser window. The function above automatically becomes a window function.
myFunction() and window.myFunction() is the same function:
function myFunction(a, b) {
return a * b;
}
window.myFunction(10, 2); // window.myFunction(10, 2) will also return 20
This is a common way to invoke a JavaScript function, but not a good practice in computer programming. |
When a function is called without an owner object, the value of this becomes the global object.
In a web browser the global object is the browser window.
This example returns the window object as the value of this:
function myFunction() {
return this;
}
myFunction(); // Will return the window object
Invoking a function as a global function, causes the value of this to be the global object. |
In JavaScript you can define function as object methods.
The following example creates an object (myObject), with two properties (firstName and lastName), and a method (fullName):
var myObject = {
firstName:"John",
lastName: "Doe",
fullName: function () {
return this.firstName + " " + this.lastName;
}
}
myObject.fullName(); // Will return "John Doe"
The fullName method is a function. The function belongs to the object. myObject is the owner of the function.
The thing called this, is the object that "owns" the JavaScript code. In this case the value of this is myObject.
Test it! Change the fullName method to return the value of this:
var myObject = {
firstName:"John",
lastName: "Doe",
fullName: function () {
return this;
}
}
myObject.fullName(); // Will return [object Object] (the owner object)
Invoking a function as an object method, causes the value of this to be the object itself. |
If a function invocation is preceded with the new keyword, it is a constructor invocation.
It looks like you create a new function, but since JavaScript functions are objects you actually create a new object:
// This is a function constructor:
function myFunction(arg1, arg2) {
this.firstName = arg1;
this.lastName = arg2;
}
// This creates a new object
var x = new myFunction("John","Doe");
x.firstName; // Will return "John"
A constructor invocation creates a new object. The new object inherits the properties and methods from its constructor.
The this keyword in the constructor does not have a value. |
In JavaScript, functions are objects. JavaScript functions have properties and methods.
call() and apply() are predefined JavaScript function methods. Both methods can be used to invoke a function, and both methods must have the owner object as first parameter.
function myFunction(a, b) {
return a * b;
}
myFunction.call(myObject, 10, 2); // Will return 20
function myFunction(a, b) {
return a * b;
}
myArray = [10,2];
myFunction.apply(myObject, myArray); // Will also return 20
Both methods takes an owner object as the first argument. The only difference is that call() takes the function arguments separately, and apply() takes the function arguments in an array.
In JavaScript strict mode, the first argument becomes the value of this in the invoked function, even if the argument is not an object.
In "non-strict" mode, if the value of the first argument is null or undefined, it is replaced with the global object.
With call() or apply() you can set the value of this, and invoke a function as a new method of an existing object. |
JavaScript variables can belong to the local or global scope.
Private variables can be made possible with closures.
A function can access all variables defined inside the function, like this:
function myFunction() {
var a = 4;
return a * a;
}
But a function can also access variables defined outside the function, like this:
var a = 4;
function myFunction() {
return a * a;
}
In the last example, a is a global variable.
In a web page, global variables belong to the window object.
Global variables can be used (and changed) by all scripts in the page (and in the window).
In the first example, a is a local variable.
A local variable can only be used inside the function where it is defined. It is hidden from other functions and other scripting code.
Global and local variables with the same name are different variables. Modifying one, does not modify the other.
Variables created without the keyword var, are always global, even if they are created inside a function. |
Global variables live as long as your application (your window / your web page) lives.
Local variables have short lives. They are created when the function is invoked, and deleted when the function is finished.
Suppose you want to use a variable for counting something, and you want this counter to be available to all functions.
You could use a global variable, and a function to increase the counter:
var counter = 0;
function add() {
counter += 1;
}
add();
add();
add();
// the counter is now equal to 3
The counter should only be changed by the add() function.
The problem is, that any script on the page can change the counter, without calling add().
If I declare the counter inside the function, nobody will be able to change it without calling add():
function add() {
var counter = 0;
counter += 1;
}
add();
add();
add();
// the counter should now be 3, but it does not work !
It did not work! Every time I call the add() function, the counter is set to 1.
A JavaScript inner function can solve this.
All functions have access to the global scope.
In fact, in JavaScript, all functions have access to the scope "above" them.
JavaScript supports nested functions. Nested functions have access to the scope "above" them.
In this example, the inner function plus() has access to the counter variable in the parent function:
function add() {
var counter = 0;
function plus() {counter += 1;}
plus();
return counter;
}
This could have solved the counter dilemma, if we could reach the plus() function from the outside.
We also need to find a way to execute counter = 0 only once.
We need a closure.
Remember self-invoking functions? What does this function do?
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
add();
add();
add();
// the counter is now 3
The variable add is assigned the return value of a self invoking function.
The self-invoking function only runs once. It sets the counter to zero (0), and returns a function expression.
This way add becomes a function. The "wonderful" part is that it can access the counter in the parent scope.
This is called a JavaScript closure. It makes it possible for a function to have "private" variables.
The counter is protected by the scope of the anonymous function, and can only be changed using the add function.
A closure is a function having access to the parent scope, even after the parent function has closed. |