Javascript Functions 101
I started learning javascript last week. The transition from ruby to javascript has been rough. I often find myself thinking in ruby rather than javascript, especially when it comes to functions. Both ruby methods and javascript functions are one of the fundamental building blocks of their respective languages. They are both blocks of code composed of a sequence of statements telling your program how to process data or execute a specific task. The two differ in several ways, however, and Javascript functions seem to be slightly more complex (maybe that’s just because I’m still a javascript noob). In order to get a better grasp of how to implement javascript functions, I decided to outline a few of the key concepts and highlight some ways they are different from ruby methods.
Syntax:
The first, and most obvious, difference between a ruby method and a javascript function is syntax. A ruby method is wrapped in a a ‘def’/ ‘end’ block. A javascript function, however, can be declared multiple ways. In each way, the function takes in an optional argument between the ‘( )’ and the block of code to be executed is placed within the ‘{ }’. The ruby method and the javascript functions below all output the same thing.
Additionally, when you call a function in javascript, you must call it with the parenthesis, hello(), without them you are simply returning the function. In general, it is really important to keep your code organized so that you can ensure the correct syntax — missing one parenthesis or curly bracket (and you will use a lot of them when writing javascript functions) will throw off all your tests & program.
Scope:
Scope is very important when declaring and executing functions in javascript. If a variable is declared outside of a function, it’s scope is considered global. A function has access to variables declared in the global scope and can use them within in the function. If a function declares another variable using the var or let keyword within it’s body with the same, a new variable is created. The variable created within the function, however, is a local variable and can only be accessed within the function.
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.
Closures:
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 ruby, we can reference a method within another method, however, that method will automatically be called when the outer method is called. In the above javascript example, we have to call both the outer and inner functions in order to get the return value of the inner function. The inner function remains private until it is called.
Callbacks:
In addition to closures, javascript functions also use callbacks. A callback is a function that is passed in as an argument to another function. Let’s say we wanted to iterate through an array of numbers and add one to each of those numbers. We could call the .forEach method on that array, but how would it know that we wanted to add one to each of those numbers. The .forEach method needs a callback function in order to properly execute the code.
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 javascript variable ‘this’ is similar to the ‘self’ keyword in ruby. It can be called within in a function and it’s value is dependent on the way in which the function was called.
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.
There is a lot more to discuss on the topic of javascript functions, they are after all, one of the crucial building blocks of the language. It might be worth writing an entire blogpost on the various ways functions are used in Object Oriented programming and how functions themselves are objects, but will save that for a later post!
Sources:
Eloquent Javascript — Functions
MDN web docs — Javascript Guide Functions