JavaScript Data Type Visualizer

JavaScript is a powerful but infamous language. Why JS is notorious [link: Wat]. Personally, I find data types confusing for someone coming from C#, Java world.

I build a small utility to visualize relationship between different data types and their prototype chain.
JavaScript Type Visualizer: jstype.heroku.com

JS data types

There are two types of data structure

  1. Primitive: boolean, null, undefined, number, string.
  2. object: everything else including Object, Array, Function, Number, String, Boolean, RegExp.

Duh, so what?

It was all good until I came across:

  1. In JavaScript, arrays, functions, regular expressions, and objects are object - Douglas Crockford

  2. All native functions inherit from Function.prototype. Number, String, Object, Array and RegExp are all functions, therefore they inherit from Function.prototype.[source]

  3. Every Object is a function and every function is Object - which one is correct? [source]. First comment on this question is ‘When you fully understand it, you will reach nirvana’.

Quest for nirvana

Even after reading Professional JavaScript for Web Developers, Essential JavaScript, JavaScript - The Good Parts and actively working on a JS project for more than 8 months, I was not confident about the relationship between function and object. It was time for some reverse engineering. As a result, I build a small utility to visualize relationship between different data types (as reported by the browser).

JavaScript Type Visualizer: jstype.heroku.com

Learnings

  1. object vs Object: One major misunderstanding was considering object and Object as same. An object is a data type which represents JavaScript variables that can hold different properties and Object is a constructor function which creates an object when invoked with new. mdn

  2. Prototypal inheritance: “When it comes to inheritance, JavaScript only has one construct: objects. Each object has an internal link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype. null, by definition, has no prototype, and acts as the final link in this prototype chain” - mdn. Though above lines seems obvious and trivial, it is the crux of JavaScript types.

  3. null object: It’s written all over in the books and articles that typeof null is object, even though it is a primitive data type. Why?
    Answer is prototypal inheritance. If ever null has its own type like typeof null -> 'dummy', then everything except primitive types (including Object, Function, Array etc) would be of dummy type. Use JSType utility for next sections.

  4. Instance functions: [only for explanation] In JavaScript, assume that all instance function defined on an object are similar to public functions defined in a Java class. When you create an object, it inherits all instance functions (and properties) defined on its own prototype, Object.prototype and null.
    Browse utility to see what all functions are defined on which prototype. A quick overview:
     var foo = { };
     // foo --> Object.prototype (proto1)--> null
     var foo = function abc() { return "hello world"; };
     // foo --> Function.prototype (proto2) --> Object.prototype (proto1) --> null
     var foo = new String("Hello World");
     //foo --> String.prototype --> Object.prototype (proto1)--> null
    
  5. Static functions: [only for explanation, todo-content editing] Constructor functions has functions which are similar to static functions defined in a Java class. E.g. Object constructor function has getPrototypeOf(), setPrototypeOf() which you invoke as Object.getPrototypeOf() instead of an instance object like obj.getPrototypeOf().
  6. Constructor Functions: It’s crucial to understand constructor function used to create object intself is a function and function in JavaScript are objects. Thus all constructor function inherit from their own prototype, Function.prototype, Object.prototype and null.
var foo = Object;
foo --> Object.prototype (proto3) --> Function.prototype (proto2) --> Object.prototype (proto1) --> null
var foo = Array;
foo --> Array.prototype (proto4) --> Function.prototype (proto2) --> Object.prototype (proto1) --> null
var foo = Function;
foo --> Function.prototype (proto5) --> Function.prototype (proto2) --> Object.prototype (proto1) --> null

Note that all constructor functions are inherited from same proto1 and proto2 because of item (4).

######Disclaimer: This article is totally based on my understanding while working on tool and not completed. Your feedback/comments/corrections are highly appreciated.