Thursday, December 17, 2015

Demystifying JavaScript objects - Part 3 of 3

Inheritance needs no introduction in programming world. It's a way by which specialization is achieved in our application. One of the way we achieve DRY principle.

Inheritance in JavaScript is achieved easily, of course less conventional, compared to other high-level programming languages.

In my earlier posts we saw a couple of ways to create classes in JavaScript. Which way should we go about is outside the scope of this post. Certainly intriguing for another post. But when I do get some skin for it, I should also be prepared for some flake. It's a very debatable subject. Although I can say, you'll not be wrong picking any one of the approach. For this post, let's focus on inheritance, I'll share samples for both approaches here, in case you have any of the 2 implementations.

Let's start by with literal notation approach. Here I created a simple "book" object with title, and author properties. Have printInformation method to print title and author information on console. Have overriden toString method for my convenience. (I am sure you can follow all of this from my code. I can stop giving a running commentary on the code and let developers do what they are good at, inspect code for themselves).

 var book = {
 title: "Some book",
 author: "Some author",
 printInformation: function() {
  console.log(this.toString());
 },
 toString: function() {
  console.log("Invoked toString method");
  return "Book: " + this.title + ", Author(s): " + this.author;
 },
 printProperties: function() {
  for(property in this) {
   console.log("Property: " + property);
  }
 }
};

book.printInformation();
var bookPrototype = Object.getPrototypeOf(book);
console.log(typeof(book));

Now that base class is created, lets go ahead creating specialization class, technicalBook (assuming technical here refers to software technology)

var technicalBook = Object.create(book, {
 programmingLanguage: {
  configurable: true,
  enumerable: true,
  writable: true,
  value: 'C++'
 },
 printAllInformation: function() {
  console.log(this.toString() + ', Language: ' + this.programmingLanguage);
 }
});

As you could see, we derived "technicalBook" from "book". We also defined an additional property "programmingLanguage". What's a technical book, without saying which language its on?

We have not also override any base class methods, but we defined a new method "printAllInformation". Along side our declaration of "programmingLanguage" property, we provided additional behavior like configurable, writable, etc on our new property. (Din't see that coming, did you?).

What if I want to Override parent class's methods?
It's simple rename printAllInformation with printInformation. That all you need to do.

What if I want to call parent class method from overridden method?
Keep reading. I have provided some explanation in my samples, next.

I have spoken to a lot of fellow JS developers who have done some good amount of work in JS. There's always a hesitation in them when it comes to code re-use through specialization (Inheritance in particular). If you use React JS, Node JS, this concept will be more than handy. Every good JS developer you look up to are extremely good in inheritance.

Function style Inheritence
Let's turn our attention to function style. Let's redo the same sample we did earlier to maintain context. Your Book class will look like the following.

function Book(title, author) {
 this.title = title;
 this.author = author;
}

Book.prototype = {
 constructor:Book,
 printBookDetails: function() {
  console.log(this.toString());
 }, 
 toString: function() {
  return this.title + " By: " + this.author;
 }
};

TechnicalBook class derived from Books will be defined as follows

function TechnicalBook(title, author, language) {
 this.title = title;
 this.author = author;
 this.language = language;
}

TechnicalBook.prototype = Object.create(Book.prototype, {
 constructor:{
  configurable: true,
  enumerable: true,
  value: TechnicalBook,
  writable: true
 }
});

With derived class defined, we will be able to invoke every base class method from derived class instance, typical to any inheritance pattern. Go ahead create instance of class TechnicalBook and invoke printBookDetails.

Make sure you pass all the needed parameters to TechnicalBook constructor. Parameters to methods and constructors has been a double edged sword in JavaScript. Remember how function overloading works in JavaScript. Same holds good for constructors too. Constructor is nothing more than a function in this case.

In my little experience, I have more often seen developers miss parameter on constructor(s), in the process end up creating half-cooked instances, which adds to over-all problem when it comes to code maintenance. Not to mention the pandemonium during release. we will look into that problem in a little bit or in a different post. 

We have defined derived class, how about adding more functions, and/or calling base class methods.

TechnicalBook.prototype.printDetails = function() {
 // this.printBookDetails();
 Book.prototype.printBookDetails.call(this);
 console.log("Language: " + this.language);
}

With this defined, we will be able to invoke every base class method from derived class. Go ahead, create instance of class TechnicalBook, invoke printBookDetails, see what happens. Again, make sure you pass all needed parameters.

Above code clearly shows a couple of things. We defined a new method printDetails. It's not available in base class. However, we did not want to redo the code in base class, hence we invoked printBookDetails from printDetails. This code tells you not only how to add a new method but also invoke base class method.

We can invoke base class methods in a couple of ways. Direct approach using this keyword is a no-brainer. Other way is using call. Both execute the same method, syntax sugar is different. However, it educates us with a new concept. I'll show that a little later. It's called "constructor stealing". Nerdy way to define child classes that instantiate base class properties. From a daily usage perspective, we could use whatever we are comfortable with.

Next up, how about overriding parent methods?

TechnicalBook.prototype.printBookDetails = function() {
 console.log("Title: " + this.title + ", By: " + this.author);
 console.log("Language: " + this.language);
}

We have printBookDetails defined in base class too. Based on the instance created, appropriate method will be invoked. But wait. Did you notice redundant code between base and derived class?

Its a big taboo in our world. We do everything possible to avoid re-doing things. Isn't that the primary objective for us to do inheritance?.

Easiest way to fix this problem is to invoke base class method, then do our customization. This is where "call" strategy we learnt above comes in handy.

TechnicalBook.prototype.printBookDetails = function() {
 Book.prototype.printBookDetails.call(this);
 console.log("Language: " + this.language);
}

This brings us to the end of this inheritance post. However we will continue to see some more examples on OOP best practices & patterns in JS OOP in my other posts.

You thought I forgot about constructor stealing, parameter handling in constructors? Nope. Not a bit. My next post will be on the best practices, that will talk extensively about them with code samples. Lets stay connected.

Monday, December 14, 2015

Demystifying JavaScript objects - Part 2 of 3

In my previous post we looked at creating classes by literal notation, there are other ways to create classes. One other way is FUNCTIONS

In this post we will take a look at more traditional approach. In addition we will also see mysteries around prototype. I'd rather say PROTOTYPE as a hidden treasure in JavaScript. Once you get a hang of prototype, you'll see how easy it is for you to do OO development. Magic by which your code will be super awesome.

Lets start by creating a simple class. Notice upper case letter for function name. It conveys, it is a constructor. Sure you'll get used it as you do more code.

function Person(name, age) {
 this.name = name;
 this.age = age;
}

var person1 = new Person("Krishnan", 35);
console.log(person1.name + ", " + person1.age);

The way we instantiate this class is with "new" keyword. That's something all of us know of. Is it not how we allocate space for our instances in other high level programming languages. Phew! For once JavaScript struck to something we now of from our earlier programming lessons. Now you wonder, what happens if you miss "new" keyword? In that case name and age get to have a global scope and you assign values to a global scope variable, and not to class scope variables.

A good framework developer would not allow such cracks in his framework. We can fix that by following some good practices in code. Will show you how in later posts, for now, lets not digress. Focus right back on OOP

We defined properties name and age without specifying how they will behave, are they writable, enumerable or configurable. If you need finer control, here's another way do it.

function Person(name, age) {
  this._name = name;
  this._age = age;

 Object.defineProperty(this, "name", {
  get: function() {
   return name;
  },
  set: function(newValue) {
   name = newValue;
  },
  configurable: true,
  enumerable: true
 });

 Object.defineProperty(this, "age", {
  get: function() {
   return age;
  },
  set: function(newValue) {
   age = newValue;
  },
  configurable: true,
  enumerable: true
 });
}

var person = new Person("Krishnan", 35);
console.log(person.name + ", " + person.age);

for(property in person) {
  console.log(Object.getOwnPropertyDescriptor(person, property));
}

OUTPUT
Krishnan, 35
_name
{ value: 'Krishnan',
  writable: true,
  enumerable: true,
  configurable: true }
_age
{ value: 35,
  writable: true,
  enumerable: true,
  configurable: true }
name
{ get: [Function],
  set: [Function],
  enumerable: true,
  configurable: true }
age
{ get: [Function],
  set: [Function],
  enumerable: true,
  configurable: true }
[Finished in 0.1s]

We created 2 properties, added getters and setters. Look into the output. We see all items defined in the class.

My 5 cents, care to hear? One reason I prefer creating classes the non-function way is, with the above definition, the following lines may surprise you

console.log(typeof(person1));
console.log(person1 instanceof Person);
console.log(Object.getPrototypeOf(Person));

OUTPUT
object
true
[Function]

You'd have expected the last line to say [object], given that your conventional wisdom from other high level programming languages dictate this to be a class. Since the constructor we defined is a Function, prototype of Person comes back as Function.

Adding more functionality
So far we defined a simple class, added properties to it. How about adding functionality or functions? In comes 'prototype'. Every instance of a class in JavaScript has a proverbial property "prototype". This property points to the prototype of current instance. What else can that be, other than its class definition.

From our sample code above, person1's prototype will be Person. Every definition in Person will be available to all its instances through prototype property. Each time we invoke a method on an instance, JavaScript uses a familiar recursive pattern to locate method definition, starting from current class. Search begins for the prototype property on current instance, if found, search operation is terminated. Else, looks for the prototype property on it base class, cycle continues, until property/method is located or it has reached top of hierarchy i.e. Object. This functionality and resolution is akin to how inheritence pattern works in high-level programming languages.

Alright, back to our prototype story. Every function defined on Person prototype will be available to all instances of Person class. Think of prototype property as a pointer. person1's prototype pointer does not contain all the definition, it rather points to where the definition will be. That can be nothing but location of Person class. This also means, any changes to Person's prototype will impact on all Person instances. With power, also comes responsibility.

Person.prototype.printInformation = function() {
 console.log("Name: " + this.name + ", Age: " + this.age);
}

console.log(person1.printInformation());

As as many instances as we have on Person, all of them will have access to "printInformation". Next obvious question is, can I add more functions in one go with this syntax or within this code block?

ABSOLUTELY, you can, but with a gotcha. Lets start with what we have and then come back to gotcha in a bit.

function Person(name, age) {
 this.name = name;
 this.age = age;
};

Person.prototype = {
 constructor: Person,
 printInformation : function() {
  console.log("Name: " + this.name + ", Age: " + this.age); 
 },
 canDrinkBeer: function() {
  return (this.age > 18);
 }
};

You did add multiple functions with ease, one thing to note is constructor parameter. In our earlier declarations, we added to prototype, but in here we are redefining prototype. Hence we have to make sure constructor property is defined. That's the only way we can have inheritance hierarchy defined or stop it from breaking (That's the gotcha.). Try removing that parameter and see what happens. You may be in for some surprise. In the worst case, it well tell you something more about JavaScript classes and objects.

Have fun working on prototype, our next hop will be inheritence

Sunday, December 13, 2015

Demystifying JavaScript objects - Part 1 of 3

Basics in JavaScript objects
JavaScript as fascinating as a language it is, needs some demystification when it comes to OOP. Even the best of programmers stumble when it comes to OOP in JS. Why? Language changes on a daily basis there are so many way to achieve same things and best of all, this language is in its metamorphosis to rule the world, if not already done.

People have one or the other editor for JS programming. I have had my luck with 3

  1. Sublime Text
  2. ATOM
  3. Web storm
Of the 3 Webstorm is the best. For small projects/applications, I'd say Sublime Text is easy and not bad. Traditionally, JS is executed as a part of HTML code. But for us in our work, we don't want to do that, why? we want to stay focussed on JS as much as possible. We'd like to write code like how we'd do C#/C++/Java etc. Write code, save it as .JS file, compile and execute. Read the following link, setup, if you like to proceed.


How to set up SublimeText3 for Javascript development?
http://calebgrove.com/articles/js-console-sublime-text

Let's start by creating a simple JavaScript object

 

var person = {
 name: "Krishnan",
 age: 30,
 printInformation: function() {
  return this.name + ", Age: " + this.age;
 }
};


"person" object is defined and available for usage. Object definition in this case was simple. But imagine you are consuming a class from 3rd party libraries or open source frameworks. You may want to look out for properties and methods that are exposed for usage. One way to do that is to look into JS files. But a more prudent approach will be to enumerate exposed properties.

Why not look into file and get a better picture?
JS does not have a very clear delineation for public and private methods/properties/fields. Hence you may be dissuade by what you see. When you enumerate it programmatically, you'll know what's available for you. As you will see down the line, we can define properties that can have their enumeration, configuration properties turned off. Meaning, they will be used for internal purposes. Why worry about them. Hope this explains, why you should enumerate. With that thought in mind, lets move on.

How do I enumerate object for its properties and methods. How do I know if a property I need is defined on the object or not?

console.log("name" in person);

Take a look at the output. We now know if "name" property is defined or not on the object. How do we know if "name" property is defined on person or in any of its base classes?

 console.log(person.hasOwnProperty("name"));

Next question, Are not all objects in Javascript devrived from "Object" class. What are the default methods/properties that my Person class has inherited. I am going to reserve that for another post on Javascript inheritence.

However, I'll give you one answer here. Yes, all objects in JavaScript are derived from Object.

We looked at one property "name" in person. In the real world applications your workers may have many more objects that have hundreds of properties defined on them. How can I find out all properties? More importantly, properties that are defined in the object that I am using.

console.log("Own properties");
for(property in person) {
 console.log("Property: " + property);
}

Alright, I have seen all properties, Can I add or delete properties dynamically? Let me answer delete first. Always start with low hanging fruits!!!

delete(person.age);
console.log("age" in person)

There are times when you as a framework developer will not want to developers to meddle with your object and its properties. In the sense, you don't want to let your objects be extensible or configurable. In other cases you don't want anyone to change the values too. Did I say too many things too fast. Let me slow down, every property, function defined in the object has multiple associated properties that tell us if they are configurable, enumerable or even writable. Following code will help us find that out. If you attempt to configure an object that's not configurable, behavior depends on execution context. If code is executed under strict mode, you'll error out. If its not strict mode, you'll not be able to do waht you intended to do on the object, you'll neither see an error. JS digests the error for you.

Now, how can I enquire for all the properties and its nature?

for(property in person) {
 console.log("Property: " + property);
 console.log('Value: ' + person[property]);
 console.log(Object.getOwnPropertyDescriptor(person, property));
}

OUTPUT

Property: name
Value: Krishnan
{ value: 'Krishnan',
  writable: true,
  enumerable: true,
  configurable: true }
Property: age
Value: 30
{ value: 30,
  writable: true,
  enumerable: true,
  configurable: true }
Property: printInformation
Value: function () {
  return this.name + ", Age: " + this.age;
 }
{ value: [Function],
  writable: true,
  enumerable: true,
  configurable: true }


All right, We are happy to see what is in person object. But is it not weird to find out that name and age properties can be easily manipulated from outside?. People who come from other OOP world despise that.

They are used to concept called "accessors" and "manipulators", hide original definitions under "private" clause. JS does not provide support "private" accessor directly. However, we can code in such a way that we could emulate OO abstraction and encapsulation ideals. To start with lets rename "name" and "age" properties and add getters and setters for the same. How do I define private properties. I'll explain them later in moderator design pattern. Please hold on until then.


var person = {
 _name: "Krishnan",
 get name() {
  return this._name;
 },
 set name(newValue) {
  this._name = newValue
 },
 _age: 30,
 get age() {
  return this._age;
 },
 set age(newValue) {
  this._age = newValue;
 },
 printInformation: function() {
  return this.name + ", Age: " + this.age;
 }
};

person.name = "Krishnan";
person.age = 30;
console.log("Name: " + person.name + "\nAge: " + person.age);

for(property in person) {
 console.log("Property: " + property);
 console.log('Value: ' + person[property]);
 console.log(Object.getOwnPropertyDescriptor(person, property));
}


Yeah, finally, something I always like to see in my class. "getters" and "setters" defined. That sort of helps, but we still have an issue.

Although _name and _age may not be apparent to users, they can still see it, if need be change the value directly on those properties too. Are there are ways to disable them and what are there implications?

Lets' start with making the object less or not extensible

Object.preventExtensions(person);
person.dob = "mm/dd/yyyy";
console.log("Is extensible: " + Object.isExtensible(person));
console.log("Is DOB defined: " + "dob" in person);
console.log("DOB: " + person.dob);

OUTPUT
Is extensible: false
false
DOB: undefined


As you could see, after making the object not extensible or unextensible, we were not able to add new property to person class. I see you smile on this achievement. Though you cannot add a property, we can still delete existing properties. How to curb that?

delete(person.age);
for(property in person) {
 console.log("Property: " + property);
 console.log('Value: ' + person[property]);
 // console.log(Object.getOwnPropertyDescriptor(person, property));
}


Sealing an object

Object.seal(person);

Now lets try to add a new property/function or delete an existing one. We'll not be able to.

What we can still do though is, change value for properties.

Enter the highest security zone. Freeze

Object.freeze(person);

Now we cannot delete or add or modify properties.