1 2 3 4 5 6 7 |
this.globalVar = { myGlobalVarsMethod: function (){ // Implementation } }; console.log(this.globalVar); // { myGlobalVarsMethod: |
Since no inner function is declared, this function object is bound to the global scope.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
this.globalVariable = 'globalVariable'; function globalFunction (){ this.innerVariable = 'innerVariable'; // true, no globalVariable defined within function scope console.log(this.globalVariable === undefined); console.log(this.innerVariable === 'innerVariable'); // true, innerVariable is defined return { innerFunction: function () { //true for both because no vars are //declared within local scope console.log(this.globalVariable === undefined); console.log(this.innerVariable === undefined); } } } globalFunction().innerFunction(); |
In the above code:
- global scope has one variable globalVariable.
- However in globalFunction function object, notice notice we have a inner function, and thus, each function’s this scope is bound to itself.
- the inner function cannot read the outer scope’s variable and thus both innerVariable and globalVariables are undefined.
- In globalFunction’s globalVariable is undefined because it is not declared in its this scope
Thus, in the example, there are separate ‘this’ objects bound to each invoking function.
Unbeknownst to many Javascript developers, there is an arguments object created within a function. It is an Array-like object (only having the property length). Arguments has three main properties, namely, callee (the invoking method), length, and caller (the reference to invoked function).
Declaring a variable arguments inside a function replaces/overrides the primary arguments object.
1 2 3 4 5 6 7 8 9 10 |
function fn (){ console.log(typeof arguments); // [object Object] console.log(arguments[0]); // DeathStar console.log(arguments[1]); // Tatooine arguments.push("Naboo"); // TypeError: undefined is not a function var arguments = "Star Wars"; console.log(arguments[5]); // W } fn("DeathStar", "Tatooine"); |
Call, Apply
Both call and apply are used to invoke a method on an object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
global.lightSaberColor = 'none'; //global variable //object var darthVader = { team: 'Empire', lightSaberColor: 'Red' }; //looks for the local lightSaberColor var var printLightSaberColor = function(){ console.log(this.lightSaberColor); //logs global lightSaberColor variable }; printLightSaberColor(); // none // Red, binds the this to darthVader object, and runs the function printLightSaberColor.call(darthVader); //call requires explicit arguments // Red, binds the this to darthVader object, and runs the function printLightSaberColor.apply(darthVader); //apply requires array |
Bind
The bind method is used to invoke methods while explicitly specifying this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
console.log("----- BIND EXAMPLE --------"); var lukeSkywalker = { mother: 'Padme Amidala', father: 'Anakin Skywalker' }; var getFather = function(){ console.log(this.father); }; // The first getFather() returns undefined because the father attribute is not set on this. //Then what is this? It is the global window object since we did not explicitly set it! getFather(); // Anakin Skywalker, this binds to object passed in, then called with () //The second getFather() returns "Anakin Skywalker" because lukeSkywalker is getFather()'s this. getFather.bind(lukeSkywalker)(); getFather(lukeSkywalker); // undefined, nothing because this is bound to global |