Today, I'm going to continue learning more about Objects and Functions as taught by Tony Alicea in his course, JavaScript: Understanding the Weird Parts.
I hope to cover and have a better understanding of ‘arguments' and spread, function overloading, closures, callbacks, and more.
arguments
and spread
When the execution context of a function is created, we've already learned that it sets up a variable environment, the ‘this' variable, and a reference to its outer environment. It also sets up the ‘arguments' variable.
arguments
contains a list of all the values (parameters) that you pass to a function.
function greet(firstname, lastname, language){ console.log(arguments) } greet('John', 'Doe', 'en'); //output is "array-like". It doesn't have all features of an array. ["John', "Doe" "en"]
Arguments in any programming language are the parameters you pass to a function, but JavaScript gives a keyword of the same name that contains them all.
Spread syntax allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected.
function sum(x, y, z) { return x + y + z; } const numbers = [1, 2, 3]; console.log(sum(…numbers)); // expected output: 6
Framework Aside: JavaScript Function Overloading
JavaScript doesn't have function overloading, per se. Function overloading is a way to send different numbers of parameters to a given function.
There are many different JavaScript patterns that can be used to simulate function overloading.
function greet(firstname, lastname, language){ console.log('I don't want to send three parameters'); } function greetEnglish(firstname, lastname){ greet(firstname, lastname, 'en'); } //I don't have to send three parameters because //I'll use the function that only takes two greetEnglish('John', 'Doe');
Conceptual Aside: Syntax Parsers
The intermediate program between your code and the computer is it's own program. It translates your code into something the computer can understand. The JavaScript engine in a browser, for example, does this. And it includes a syntax parser, which determines if your code is valid.
Before your code is executed, the syntax parser decides what it's going to do with your code.
Dangerous Aside: Automatic Semicolon Insertion
In JavaScript, the JavaScript engine's syntax parser automatically inserts semi-colons where it expects semi-colons should be. I does this by looking for certain words that are followed by a carriage return. If it doesn't have a semi-colon, the engine will attach one behind the scenes. This is why semi-colon are “optional” in JavaScript.
- You should want to put your own semi-colons in your code as opposed to relying on the JavaScript engine.
- It can cause problems in the case of a return statement.
//Case 2 above: function getPerson(){ return { firstname: 'Tony' } } console.log(getPerson()); //In the above code, the object will not be returned. //The syntax parser will add a semi-colon and the //function will be escaped by the return statement. function getPerson(){ return { firstname: 'Tony' } } console.log(getPerson()); //In the above code, the object WILL be returned. //The syntax parser doesn't expect a semi-colon //because it sees a { instead of a return carriage.
Framwork Aside: Whitespace
Whitespace – Invisible characters that create literal ‘space' in your written code (Carriage returns, tabs, spaces).
In JavaScript, you are allowed to use whitespace very liberally. The syntax parser ignores whitespace which allows for lots of comment. This means that you may see lots of libraries with variables on their own lines:
var //first name of person firstname, //last name of person lastname, //the language // can be english language;
Immediately Invoked Function Expressions (IIFEs) in JavaScript
//Using an IIFE //Function is invoked immediately after its creation. var greeting = function(name){ console.log('Hello' + name); }();<--invoking the function with no parameters var greeting = function(name){ console.log('Hello' + name); }('John');<--invoking the function with John as a parameters
IIFES allows you to invoke functions at the point when they are created.
If you want a function statement to stand alone, you can't do this:
function (name) { return 'Hello' + name; }
…because the syntax parser expects the name of the function like this:
function myName (name) { return 'Hello' + name; }
So, to make a function statement that is an expression which is created on the fly, you must wrap your function in parenthesis like so:
var firstname = 'John'; (function (name){ return 'Hello' + name; }(firstname));
Framework Aside: IIFEs and Safe Code
Because of IIFEs, separate executive contexts can be created, which prevents variable names from “crashing” into each other. Each variable takes up its own memory space.

Understanding Closures in JavaScript
Execution stacks “closes in” its outer variables to allow access to the memory space in the outer environment.
Closures are simply a feature of the JavaScript language. It's not something you create. The JavaScript engine always make sure you have access to the variables it supposed to have access to.

Closures and Callbacks in JavaScript
Callback Function – A function you give to another function, to be run when the other function is finished. So the function you call (invoke) ‘calls back' by calling the function you gave it when it finishes.
Callback functions take advantage of closures.
call()
, apply()
, and bind()
All functions in JavaScript get access to some special methods including call(), apply(), and bind(). All three has to do something with the ‘this
‘ variable.
var person = { firstname: 'Tony', lastname: 'Robbins', getFullName: function(){ console.log(this.firstname + ' ' + this.lastname); } }
The bind methods allow you to pass an object that will take the value of the this
variable.
var logName = function(lang1, lang2){ console.log('Logged: ' + this.getFullName()); console.log('Arguments: ' + lang1 + ' ' + lang2); } //using bind, the logPersonName has access to the person object var logPersonName = logName.bind(person); logPersonName('en', 'es');
Using call() allows you to call a function but let's you pass the object that will take the value of the this
variable.
//using call, the logName can be called with the person object
//to which the this
keyword will be binded.
var logPersonName = logName.call(person, 'en', 'es');
logPersonName();
//Unlike bind, call actually executives the function
//bind creates a copy.
apply()
does the same as call, but apply()
requires an array as arguments.
var logPersonName = logName.apply(person, ['en', 'es']); logPersonName();
The above methods are good for “function borrowing”.
person2 = { firstname: 'Jane', lastname: 'Doe' } //borrowing from the person2 object person.getFullName.apply(person2);
It's also good for “function currying” because with bind you're simply making a copy.
Function currying – creating a copy of a function but with some preset parameters. Vary useful in mathematical situations.
function multiply(a,b){ return a*b; } var multipleByTwo = multiply.bind(this, 2); //the above is the equivalent of permanently setting the //first function with the parameter of '2'
What is Functional Programming in JavaScript?
Using first class functions to your advantage to pass functions to and from other functions to get values.
Returning functions from functions or giving functions to functions to simply your code as much as possible.
For example:
var arr = mapForEach(arr1, function(item){ return item *2; });
Recommended JavaScript Libraries to read to gain more understanding of how functional programming works in practice:
Underscore.JS – Underscore is a JavaScript library that provides a whole mess of useful functional programming helpers without extending any built-in objects.
Lodash – A modern JavaScript utility library delivering modularity, performance & extras.
Leave a Reply