Edit in JSFiddle

function assert(value, desc){
    var res = $("#results");
    var li = document.createElement("li");
    li.className = value ? "pass" : "fail";
    li.appendChild(document.createTextNode(desc));
    res.append(li);
  }

// every function has a name property. In case of anonymous functions its empty string
assert(assert.name === "assert","Name of assert function: " + assert.name);

// anonymous function
var fun = function(){return this;};
assert(fun.name === "","Name of anonymous function is empty string");

// function reference
var assertRef = assert;
assert(assertRef.name === "assert", "Name of function still remains the same");

// There are 4 ways to invoke a function
// 1 normal way - in this case the function context is window object (=this)
function normalFunc(){
	return this;
}
assert(normalFunc() === window, "function called normally, this = window");
//////////////////////

// 2 as a method on a object - in this case the function context is the calling object
var car = {
    drive: function() {return this;}
}
assert(car.drive() === car, "function called as a method, this = calling object");
//////////////////////

// 3. as a constructor
// constructor is just a function call done with new keyword
// constructor naming convention is to have the name starting with capital letter
function Person(n, dob){
    this.name = n;
    this.dob = dob;
    this.age = function(){
    	return new Date().getYear() - dob.getYear();
    };
}

// 3 things happen when a constructor call happens
// an empty object gets created
// this object is passed to the function as function context (=this)
// if no return value is provided, this object is returned
var p1 = new Person("Roger Federer", new Date(1981, 08, 08));
var p2 = new Person("Sachin Tendulkar", new Date(1973, 04, 23));

assert(true, p1.name + "'s age : " + p1.age());
assert(true, p2.name + "'s age : " + p2.age());
////////////////////////

// 4. using call and apply
// call and apply allow us to change the context in which the function is called
// difference between call and apply is that call takes comma separated list of arguments while apply takes an array
var abc = {};
var sum = 0;
function callApplyDemo(arg1, arg2){
    sum = arg1 + arg2;
    return this;
}

assert(callApplyDemo(4,5) === window && sum === 9, "Call Apply Demo : context is window and sum is 9");
assert(callApplyDemo.call(abc, 1,2) === abc && sum === 3, "Call Apply Demo : context is abc and sum is 3");
assert(callApplyDemo.apply(abc, [3,4]) === abc && sum === 7, "Call Apply Demo : context is abc and sum is 7");
////////////////////////

//anonymous functions are used as references
var dog = {eat : function(){return "eating";}};
var cat = {eat : dog.eat};
dog = {};
// this still works because the cat.eat got a reference to anonymous function
assert(true, cat.eat());
////////////////////////

// function's length property gives the number of named arguments with which the function was declared
function f1(a){}
function f2(a, b){}
assert(f1.length === 1, "f1 has 1 named argument");
assert(f2.length === 2, "f2 has 2 named arguments");

// function's argument property gives all the arguments passed to the function
// a javascript function can be called with more arguments than the function definition
// the remaining arguments can be accessed via the arguments property
function f3(a, b, c){
    return arguments.length;
}
assert(f3(1,2,3,4,5) === 5, "5 arguments passed");
assert(f3(1,2) === 2, "2 arguments passed");

///////////////////////
// creating functions using Function constructor
// one advantage of creating a function this way is that no closures are created 
var doSomething = new Function("str1", "str2", "return str1 + str2;");
assert(doSomething("Hello", " world !") === "Hello world !", "another way of declaring function works");
<div id='results'/>
body{
    margin:10px;
}

.pass{
  color:green;
}

.fail{
  color:red;
  text-decoration:line-through;
}