/* Immediately Invoke Function Expression */
(function IIFE(){
    console.log("Hello!");
})();



	/* First-Class Function (nested function) */
function makeAdder(x){
    // inner function add() uses 'x' for its closure over it
    function add(y){
        return y+x;
    };
    return add;
}

// record x as 1 / 10 and leave inner y later
var plusOne = makeAdder( 1 );
var plusTen = makeAdder( 10 );

// pass the 3 / 41 / 6 to the inner y
plusOne( 3 );
plusOne( 41 );
plusTen( 13 );



	/* this identifier */
function foo(){
    console.log( this.bar );
}

var bar = "global";
var obj1 = {
    bar: "obj1";
    foo: foo
};
var obj2 = {
    bar: "obj2";
};

foo();				// "global"
obj1.foo();			// "obj1"
foo.call( obj2 );	// "obj2"
new foo();			// undefined



	/* Prototypes */
var foo = {
    a: 42
};

var bar = Object.create( foo );
bar.b = "hello world";

bar.b;				// "hello world"
bar.a;				// 42 // delegated to 'foo'



	/* Polyfilling */
if(!Number.isNaN){
    Number.isNaN = function isNaN(x){
        return x !== x;
    };
}



	/* Transpiling */
// turn
function foo(a = 2){
    console.log(a);
}
// into
function foo(){
    var a = arguments[0] !== (void 0) ? arguments[0] : 2;	// void 0 === undefined
    console.log( a );
}