On Javascript Classes

Originally this blog aimed to cover both technical aspects and the philosophy issues related to my Theodorus project (which I’m somewhat shameful to say isn’t really progressing as I’m busy with other stuff, such as blog-writing). So this post is going to be very technical and probably won’t interest some of the demographics, yet as I write to my own amusement you may choose to skip this one, or not.

As most of modern day programming languages (ES6 included) have classes, we’ve grown used to them, but as originally javascript works differently, I believe it forces us to a better understanding of what classes actually are. The original “C” didn’t have classes either, but it had “structs”, which is a collection of other structs and basic type variables, like integers and array of characters (later to evolve to strings). And then someone came up with the brilliant idea of adding methods into those structs, and thus C++, the upgraded version of C, had classes. So now we have classes which are strongly related to Object-Oriented-Programming (OOP). The idea is to encapsulate methods and information regarding a certain business-logic concept. This assures “safer” interaction between several concepts as they are forbidden from touch each other private parts.

OOP is bad. But our head is so wrapped around it, it’s kinda hard to think past it, and here is where javascript comes to the rescue. Javascript, being the only prototypal language, talks about different scopes, where each function creates a new scope on top of the current scope, while keeping all underlying scopes available, so this code will work:

(function external() {
  var foo = 1;

  (function internal() {
    var bar = 2;
    console.log (foo+bar); // output 3
  })();

  console.log (bar === undefined); // output is true
})();

The “bar” variable existed only within the internal function and once it passed, it died. but note that “foo” variable was available in the internal function as well. How about this code:

(function the() {
  var foo = 1;
  
  (function plot() {
    var foo = 2;

    (function thickens() {
      console.log (foo); // output 2
    })();

    (function further() {
      var foo = 3;
      console.log (foo); // output 3
    })();
  })();

  console.log(foo); //output 1
})();

As the scopes are stacked one on top of the other, each function will first find the nearest variable with the name it’s looking for. It’s worth mentioning, though, that accessing lower levels of the scope is more expensive than the immediate levels so it is better to pass the variables along.

However, despite creating layers of scope, the magical word “this” which is often used in many languages still points out to the enclosing object, and in our example – it’s the same object. But we can create a new enclosing object using the word “new”:

function Bar(){}

Bar.prototype.whoAmI = function () {

return this;

}

var foo = new Bar();

console.log(this); // output "Window"

console.log(foo.whoAmI()); // output "bar(){}"

you might have noticed the word “prototype” there. Javascript functions have an object attached to them called prototype, which is a collection of functions that all new instances of the enclosing object will “inherit”. And that’s great, because I can create an object, let’s say “foo”, which is an instance of “Bar” and if now I’ll add a new method to Bar’s prototype, foo will be updated as well!

function MyClass(){}

var instance = newMyClass();

console.log(typeof instance.myMethod); // output "undefined"

MyClass.prototype.myMethod = function () {
  return true;
}

console.log(typeof instance.myMethod); // output "function"

So unlike any other language, with javascript I don’t need to initially declare all the class’ capabilities. I can do it whenever I want, if I want. I can also have my class inherit several prototypes. so my Robo-dog can have both dog and robot attributes, and not forces to extend only one of them.

So finally, look at this code:

function MyClass() {
  this.constructor.apply(this, arguments);

  // list all exposed functions:
  this.main.foo=this.external.bind(this)

  return this.main;
}

// list all functions, internal should start with '_'
MyClass.prototype = {
  constructor: function () {
    console.log(arguments); // output: 1,2,3 along with other stuff
  },
  main: function main () {
    return 'main function running';
  },
  external: function external() {
    console.log(this._internal());
    return 'bar'; 
  },
  _internal: function internal() {
    return 'internal';
  }
};

myInstance = new MyClass(1,2,3);
myInstance(); // output 'main function running';
myInstance.foo(); // output 'internal' and 'bar'

This code has some nice gems in it as it obfuscate (but not fully hide) code you don’t want everyone to access. It’s puts away the constructor in a separate, more manageable, function; it clearly lists all the function we would like to expose, and allow us to have external name (in our case “foo” is internally called “external”) and if we expose only the created instance and not the class itself, no one would be able to see the code of “_internal”.

So in conclusion, Javascript classes are not so much about OOP-driven, rather than a tool to manage your code better. It’s not about working hours on end to define your interface and abstract classes only to realize the world isn’t modeled as you think (been there, done that), rather than a way to group functions together and say “hey, dataObject, I want you to bark().” –

DataObject.prototype.bark = bark;
dataObject.bark();

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: