If you were to change the above method so that you are calling console.log() within the function, the output would change because console.log() would now be able to access the local variable.
A closure is a block of code that references a specific local variable defined by a surrounding function. Consider the following example:
The outer function takes in one argument (a number by which we will multiply another number) and returns an different function. The inner function takes in one argument as well (a number that we want to multiply by the second one). That second function also relies on the first argument however, and cannot be executed without calling the first. We can call the outer function with an argument and save it in a variable to make it easier to call on later. What we are doing is simply calling the function (making the original argument available to the second function) and then calling the second function to access the final return value. Using the same example above, the following two ways of calling these functions are the same.
In the above example, we passed in an anonymous function that took in one argument, ’n’ — the element in the array- and then instructed the outer function to add 1 to each element in the array that forEach was called on.
this and Functions:
The default value of ‘this’ is the global window object. If type ‘this’ without any context in your console the return value would be as follows:
This is an example of a baseless function call. Baseless functions either return ‘undefined’ or the global window object.
When you call ‘this’ on a method call, the owner becomes the object that is calling the function. In the example below, if I call logThis() on the object isa, the function returns the value of this, which is the object in which the function was defined. Taking it one step further, if you call logThisName() on isa, it returns the value of the object’s attribute name, “Isabelle”.
In order for the execution context to be the object, the method must be called on the object.
You can use the ‘call’ & ‘apply’ methods to execute functions with a specific execution context. ‘Function.prototype.call’ and ‘Function.prototype.apply’ take in an argument for which you would like to assign the value of ‘this’ to and any other optional arguments you would like to pass into the function (note: when using ‘apply’, the optional arguments must be passed using an array).
In the example above we declared a function called fullName within the person object. As expected we were able to call it on the person object. If were to try to call on person2 we would have received an TypeError as that function is not defined within the scope of person2. By using ‘call’, however, we are able to pass in person2 as an argument and change the execution context to the person 2 object.