Functions

Named functions are declared using the function keyword followed by the name of the function, a parameter list, and a block of code.  In the example below, the function named sum has two parameters named x and y, and returns the value of x + y.

function sum(x, y) {
    return x + y;
}

Since variables don’t have types when they”re defined, this function attempts to apply the + operator on v1 and v2 regardless of their types. The + operation is overloaded so can work different types.  If either argument is non-numeric, both arguments are cast to strings.

var x = sum(1,2);
console.log(x);                         // prints 3

console.log(sum(3.5, .25));             // prints 3.75
console.log(sum("hello ", "world"));    // prints "hello world"
console.log(sum(true, true));           // prints 2

console.log(sum("hi",2));               // prints "hi2"
console.log(sum(2, {name: "alice"}));   // prints "2[object Object]"
console.log(sum([1,2,3], [2,3,4]));     // prints "1,2,32,3,4"

Named functions are loaded into memory and available at the start of the script.  This is called hoisting and is done during a preprocessing phase.

console.log(sum(1,2));      // called before declared - ok

function sum(x,y) {            // the name sum is hoisted
    return x + y;
}

Unnamed Functions

We can define unnamed functions and assign a variable equal to a reference to the unnamed function.   For example, below we create a variable named errMssg and set its value equal to the reference of an unnamed function that prints to the console an “Error” followed by the value of its argument.

var errMssg = function(x) {
    console.log("Error: " + x);
};                               // must include ; since its an assignment statement

errMssg("Can not compute");      // call using the function reference

Since the variable hold just a reference, not unlike a reference to an object, multiple variables can hold the same reference.

var dup = errMssg;
dup("Out of bounds");

Function references are not hoisted, so we can only call a function using a function reference after the reference has been assigned.

foo();                        // Error: foo is not hoisted

var foo = function () {       // function not hoisted
    console.log(“foo”);
}

Passing Function References

You can pass and return references to functions.

function foo(x) {
    console.log(x);
}

var bar = function(x) {
    console.log(x);
};

function run(fun, str) {
    fun(str);
}

run(foo, “Out of memory”);     // pass named function
run(bar, "Lost signal");       // pass function reference

Another Example

function sum(x,y) {
    return x + y;
}

function run(fun, x, y) {
    return fun(x, y);
}

var x = run(sum, 1, 2);
console.log(x);

Function Internals

Two special properties exist inside a function object: arguments and this.

The arguments property holds an object that contains the values that are passed into the function.

function errMssg(x) {
    console.log(arguments);    // prints [object Arguments] {
}                              //          0: "Testing 1 2 3"
                               //        }

errMssg("Testing 1 2 3");

The arguments object has a property named callee that holds a pointer to the function that owns the arguments object (i.e. the function itself).

function foo() {
    console.log("foo");
    return arguments.callee;
}

var self_ref = foo();
self_ref();

The this Object

Every function is executed on some object.  By default functions are called on a global object named window.    This object is called a context object and has properties like any other object.  The global window object has many properties, including properties for each global variable declared without using the var keyword.

We can access within a function the context object that a function is executed on.  To do so we can use the this property.   For example, below we declare a global variable named color and print its value within sayColor() by

  1. accessing the global variable directly
  2. accessing the global variable through the this object which is the window object
  3. accessing the global variable through the window object
color = "red";

function sayColor() {
    console.log(color);          // prints "red"
    console.log(this.color);     // prints "red"
    console.log(window.color);   // prints "red"
}

sayColor();

We can also call a function on an arbitrary object.  In the example below, this refers to the object whose reference is stored in the variable obj.

function sayColor() {
    console.log(this.color);
}

var obj = {
    color: "blue",
    sayColor: sayColor
};
obj.sayColor();        // prints “blue”

The caller Property

Every function has a caller property that holds a reference to the function that called this function.

var outer = function() {
    inner();
}

function inner() {
    console.log(arguments.callee.caller);
}

inner();     // prints null
outer();     // prints the code of the outer() function

Other Function Properties

Every function has a property named length which holds the number of arguments the function expects.

function foo(x) { }
console.log(foo.length);   // prints 1

Each function also has three methods named apply(), call(), and bind().  The apply() and call() methods allow us to change which context object the function executes on.  This allows us to write a generic function to be used for arbitrary context objects.

window.color = “red”;
var o = {color: “blue”};

function sayColor() {
    console.log(this.color);   // recall this points to the context object
}

sayColor();                    // red - the default context object is the window object
sayColor.call(window);         // red – passing in window explicitly

sayColor.call(o);              // blue

The bind() method takes a context as an argument and creates a new function instance whose context object is set to the argument.  This allows us to create functions that operate on a specific context object.

window.color = “red”;
var o = {color: “blue” };

function sayColor() {
    console.log(this.color);                   
}

sayColor();      // recall the default context object is the window object

var oSayColor = sayColor.bind(o);  // binding o to this inside the function oSayColor
oSayColor();                       // blue

© 2018, Eric. All rights reserved.