Hackernoon logoJavaScript — A Sneak Peak into the Essentials (Part 3) by@berlin.robotics

JavaScript — A Sneak Peak into the Essentials (Part 3)

image
Berlin Robotics Hacker Noon profile picture

@berlin.roboticsBerlin Robotics

This blog post is for developers who already know how to write software and want to learn about Javascript. I am not teaching you how to write software because I assume you might code in a different language. I also assume that even Javascript — Ninjas enjoy some drop in conversations of topics they might or might not know.
  1. Syntactic sugar
  2. Javascript patterns / Objects in JavaScript
  3. Functions in JavaScript
  4. “this” as in pointing to this
  5. OOP (object oriented programming)

Functions in Javascript

Functions are critical to how Javascript works. This blog post will not be able to deal with every aspect of Javascript functions but I will mention the essentials which make Javascript more usable. You will find a link at the end of this post that will redirect you to a very comprehensive source for functions.

They provide a group of reusable code and can be called anywhere in your program. Functions can be adopted for various contexts and scope can be encapsulated and preserved. They behave different from other languages you might know and have a specific order on how they are called. Javascript functions can be used either as function or as an object. Javascript functions can be:

  • A normal function construct
  • An Anonymous function
  • Or a normal function with an assigned variable
// Normal function construct function
function myFunction(arguments){
// some code
};
// An anonymous function
myFunction = function (arguments) {
// some code
};
// A normal function construct with an assigned variable
myFunction = function myFunction(arguments) {
// some code
};

I am pretty sure you have seen at least one of them already? If so, you should know about their context and behaviour.

Javascript Context

There are certain applications that expect you to declare functions inside a statement. It is not very common but when you do it use the following example as boilerplate. This is supported in all current browsers using assigned anonymous functions, and this is the correct way to achieve the desired effect:

var functionName; 

if( someCondition ) {
functionName = function () { ... };
}

These functions can then be called when needed, and the code contained within them will be run. To call a function there are typically these methods:

  • myFunction(listOfVariables);
  • window.myFunction(listOfVariables);
  • object.onEventName = myFunction;

I can’t count the number of JavaScript developer candidates I’ve interviewed who couldn’t tell me the difference between a function declaration and a function expression and who had no clue what an immediately invoked function expression is. I am not ranting about it, but I do :D

Self-invoking Javascript functions

A pattern used in Javascript is the so called self-invoking functions. A self-invoking anonymous function runs immediately when it gets created at run-time. To make you aware of how this looks like, here is the format of self-executing anonymous function wrapping some code:

(function(){
// some code…
})();

Interestingly, if you look at the source code of jQuery, you will see that everything is wrapped in between in order to establish a new context:

(function( window, undefined ) {
// jQuery code
})(window);

If you are in a situation where you want to run a piece of code repeatedly or in case you want to establish a new scope. A new scope is important in case you are using other plugins and Javascript vendor files that might use your variables, too, and interferes with your global namespace. Lets assume we have a variable in the global scope which is accessible just by calling it:

// app.js
var myVariable = ['this','is','my','message'];

// another.js
if(myVariable){ // true
console.log('your var is global');
}

This is actually not considered best practice. myVariable will be added to the window scope and is visible in all other files of your app. What you want to do for each files is, you want to establish a scope for your var by using a self-envoking function. Let’s try that for a moment:

(function(){ 
var myVariable = ['this','is','my','message'];
})();

// another.js
if(myVariable){ // false because it it undefined
console.log('your var is global');
}

To solve this problem you can use a self-executing anonymous function and create an encapsulated context for this variable. So lets refactor that function a little bit to show you something funny. It is actually only funny if you know what Javascript is doing in this situation.

(function(){ 
var myVariable = ['this','is','my','message'];
for(var i in myVariable) {
setTimeout(function () {
// will be exectured delayed by 10 milliseconds
console.log(myVariable[i]);
// output: message message message message
},10);
}
})();

So what happens here? It actually prints messages four times. So what people might think is lets just lower the setTimeout time to one and every time you print it it will return the correct sentence from the array, not. setTimeout delays the execution, hence, by the time it is called i will already be “message”, or 3 since we are dealing with an array.

So in order to show you how to fix that we have to refactor the function in a less intuitive way.

(function(){
var myVariable = ['this','is','my','message'];

var say = function (i) { // the variable i will
setTimeout(function () {
console.log(myVariable[i]);
// output: message message message message
},10);
};

// So by the time i is executed it is no longer referring
// to this i in the for loop it is referring to the
// scoped i inside the say function
for(var i in myVariable)
{
say(i); // output: this is my message
}
})();

What you essentially have at this point is an encapsulated scope within a scope. Remember, when ever you call say this i is handed to this function and creates a new function scope. So by the time the function is called the i doesn’t really refer to the i in the for loop anymore. It refers to index. This is a very powerful concept within Javascript in order to create a separate context. Let me know if you ever had that problem in the past, down in the comments area.

Closure pattern

We have a function that references a variable outside the function. Let’s refactor the last example to make it a closure and to make it work in this context.

(function(){
var myVariable = ['this','is','my','message'];
    var say = function (i) { // the variable i will scoped
return function () {
console.log(myVariable[i]);
// Will be called later.
};
};
    // So by the time i is executed it is no longer referring 
// to this i in the for loop it is referring to the
// scoped i inside the say function
for(var i in myVariable)
{
setTimeout(say(i),1000); // output: this is my message
}
})();

This concept is a common pattern for a closure function. A closure is a wrapping function that captures an argument and that arguments captures that context inside of the function. This function then returns another function who’s sole purpose is to be called at a later time. It utilises the argument which was initialised in its scope. This is powerful but you to learn it until you get it right. This brings us to another common pattern called the module pattern.

Module pattern

This pattern is really helpful when you want to encapsulate private functions and variable to get access to. Furthermore, the module pattern exposes a public api which you can use to work with and to build your app with. Let’s look at a nice example for a module pattern:

var MODULE = (function () {
var privateVariable = 1;

function privateMethod() {
// do something in here
}

return {
moduleProperty:1,
moduleMethod:function () {
/**
* A function that can utilizes a private method
* or a private variable.
*/
}
};
}());

Notice that we’ve declared a global module named MODULE, with two public properties: a method named MODULE.moduleMethod and a variable named MODULE.moduleProperty. In addition, it maintains private internal state using the closure of the anonymous function. Also, we can easily import needed globals, using the pattern we learned above. This pattern is highly used in building plugins and translates easily into another pattern called CommonJS.

CommonJS

When we say an application is modular, we generally mean it’s composed of a set of highly decoupled, distinct pieces of functionality stored in modules. As you probably know, loose coupling facilitates easier maintainability of apps by removing dependencies where possible.

The CommonJS module proposal specifies a simple API for declaring modules server-side and unlike AMD attempts to cover a broader set of concerns such as io, filesystem, promises and more.

CommonJS Javascript is been used a lot in NodeJS. So if you are doing a lot of NodeJS development you’ll see this often. Essentially what you are doing is you are assigning the class interface to a module.export. To make this work you don’t need a self-executing anonymous function.Let’s get rid of the extra round brackets:

/**
* Define more behaviour we would like to expose.
* And expose foobar to other modules as well.
*/
exports.myFunction = function myFunction(){
this.one = function(){
console.log('Hello one');
}

this.two = function(){
console.log('Hello two');
}
}

/**
* Access the module relative to the path where both usage
* and module files exist in the same directory.
*
@type {exports.myFunction|*}
*/
var myFunction = require('./myFunction').myFunction,
test = new myFunction();
/**
* Make use of exported variables
*/
test.two(); // output 'Hello two'

As a good practise suggestion, when you are dealing with functions. Don’t use anonymous functions. The reason is, assume you have to debug minified code and you deal with lots of anonymous functions. You will most likely throw in the towel and start from scratch. It is such a pain!

I believe this is enough about functions since a lot of it has been covered else where. So check out the links below and I am going on to part four covering “this” keyword and scope.

Email — [email protected]

Twitter — @MHerszak (twitter.com/MHerszak)

Want to know about the way in which I work? Great, you can get started with an overview of just how I approach a project right here.

Comprehensive blogpost about all aspects of Javascript functions will be found here. Very good indeed!

Server-side usage of CommonJS patterns:

Originally published at www.browserstudios.com on December 21, 2015.

Tags

Join Hacker Noon

Create your free account to unlock your custom reading experience.