Introduction to Node.js: What Type of Language is JavaScript?


Jamison Prianos, Accusoft Software Development Manager, SaaS

This post is part of a blog series that provides an introductory overview of Node.js. To start at the beginning, read Part 1: What Makes Node So Popular? Today's post will discuss some of the characteristics of JavaScript as a language.

For those of us who started programming when procedural was the only way to go, JavaScript is a fully-working, imperative, and procedural language. You can go top down, you can have variables that are global in nature, you can change their state, and you can read their state. Today, we're going to delve a little more into what type of language JavaScript is.



Looking at the piece of code here, you can see we have a single function that does some sort of synchronous task.

JavaScript Language

  • We keep a state.
  • We set the state to processing.
  • We loop through and run this function.
  • We set the state to completed.

The task's length is the global variable of things that get added in. It's a global member of this task's array. All of this is something that could be copied and pasted with some syntax changes to PHP, C, COBOL, or Fortran. You could write the simplest procedural thing you want and do it in JavaScript with Node.



JavaScript is also an object-oriented language—sort of. JavaScript does not natively support default object-oriented processes. It has a prototypal inheritance method, which means you can modify the prototype of anything that you define. This makes it so that after an object is declared, you can go append methods, modify and remove methods, or basically mutate anything you want in JavaScript after it's been declared. (We'll get into that more a little later.)

With last year's release of the language (ES2015), they do now have the actual ‘class’ keyword, which basically desugars to prototype stuff, but it lets you say `class myClass` and treat the object line a traditional class.

JavaScript Language

So in this example, I define the task runner, stick a new task in it, and then after it's been defined and the object exists out there, I now modify its prototype to add a new function. Then I can run it. In most languages, that would have needed to be defined previously, so you cannot, at runtime, modify how this thing works. JavaScript just happily lets you break all kinds of things, but allows for some really cool options for extending objects that were written by third-party libraries, and it's basically the crux of how all of those client-side libraries like JQuery and Underscore work. They hijack the native elements in the browser, and they give you control of them.


JavaScript is also a functional language—sort of. You can write functional code in JavaScript. It is not purely functional, in that it will let you mutate state and use global variables. Again, JavaScript is going to let you do whatever you want. However, you can write fully functional code, so functions are a first-class citizen in JavaScript. That means they are treated like any other object. You can pass them around, mutate them, move them from one function to another, take one function and pass it to another library and have it replace its own inner workings with your function.

JavaScript Language

This example is too complex for what it does, but we have functions that will double the value, add five to that value, and put an X at the end of it. And then we make a function that takes any number of arguments, and composes them as a chain of functions—so F of X of G of Y, and make a new function. This defines the new function that composes all those together. So anything we pass here now we will take all three of those numbers and process them. It's going to take the number (3), double the value (6), add 5 (11), append an X, so the output of this is going to be 11x 19x 9x. All of that by taking all these functions, composing them, and passing them as values. You treat functions no differently than you treat a number or a string or anything else. In fact, you can take a function variable and recast it to a string to see the name of the function. They are fully first-class functions.

If you're using JavaScript in this mode in functional programming, it is on you to verify that you don't mutate state and change the world around your functions. The whole point of functional programming is everything can be modeled as, "this input, into a black box function, gives this output." As soon as you change this global variable, the increment counter, you're not functional programming anymore, you're back into the procedural world. This makes a very maintainable code because unit testing becomes very simple with functional code. Checking a chain of what happened and what calls went where becomes very simple and building trees of your logs becomes very simple with functional code. JavaScript is great at doing this kind of work as long as you have the forethought to stay in that mode, and the willingness to do code review, and tell people when they mutated states.



Finally, JavaScript is a dynamic programming language. As we mentioned, you can change everything. We don't statically type anything in JavaScript. We do duck-typing, so if something looks like a number then it's a number. If it looks like a string, it's a string. If you can run it, then it's a function. Everything is interpreted in JavaScript. There's no pre-compilation. Now, the more advanced things get with Chrome and with V8, there's lots of just-in-time compiling that happens. However, as far as you as a developer are concerned, it's being interpreted, so everything is fully mutable. You can take things that are built-ins of the language, and you can completely overwrite them.

JavaScript Language

As we see here, console.log spits something out. So here's our output—Hello, World! It's like we'd expect. We can then grab that to another function and override it with a new function that figures out the date and prepends it. And now, anywhere else in our code, every console.log we do we throw a timestamp in front of it.

This is why it's so powerful to be able to mutate things. Doing something like this in a language that's managed and requires you to define everything ahead of time isn't impossible with language internals. You have to write your own mylogger.log, and then everywhere in your code, replace console.log with mylogger.log. This lets us put this chunk of code as a library in our clients-side text, right in line of our HTML page, and now every library that runs, everything in my third-party libraries, everything that I have no access to, all their logs suddenly have time stamps on them. It's very powerful but also very dangerous in that you can completely break third-party libraries by changing dependencies that were expecting to be there. So, it's important to use that carefully and remember that with great power comes great responsibility.

Stay tuned for our next post, which will focus on variables and truth within JavaScript.

Jamison Prianos is a Software Development Manager in the SaaS division of Accusoft Corporation. In addition to coordinating engineering efforts for his teams, Jamison acts as an evangelist for solid Node development patterns and specifically microservices both within and outside of Accusoft, while also holding on to actual development work for dear life.

Share: Tweet about this on TwitterShare on FacebookShare on Google+Share on LinkedInEmail this to someone

Related posts

TeamCity Dependencies
Visualizing TeamCity Dependencies with Python
Read More >
reactive javascript
Vue.js: Embracing Reactive JavaScript Without Losing Your Mind
Read More >
ImageGear C++ samples
A look at ImageGear C++ Samples
Read More >

Join the discussion.