Javascript Prototyping

kuniga.me > NP-Incompleteness > Javascript Prototyping

Javascript Prototyping

18 May 2014

Javascript is a programming language based on the concept of prototypes. It also allows us to write object-oriented code using prototypes, but if we don’t understand how they work it can get confusing.

In this post we’ll talk about prototypes and we can use them to write code in a more familiar object-oriented way.

Objects

Objects in javascript are key-value pairs, called properties, the key, or property name, is either a string or a number and the property value can have arbitrary types, including strings, numbers, functions and other objects. If the property is a function, we can also refer to it as a method.

The basic way to create an object is:

There is a special object already defined called Object. One of its properties is getOwnPropertyNames, which is a function that takes an object and returns an array containing the name of properties defined in that object:

Note that it returns getOwnPropertyNames, since it’s a property. Another interesting property returned is prototype, which is an object.

All objects will inherit the properties in the prototype object. Let’s see which properties are there:

Let’s take a look on the properties of a regular object:

It won’t list the properties inherited from Object.prototype because getOwnPropertyNames, as the name suggests, only lists properties defined at that object, not those inherited. But we can verify it exists by doing:

We can override the properties inherited

We can also add more properties to Object.prototype so it’s available to all other objects:

Observe that even though we added the custom property after creating object a, the method a.custom() exists is available. This is because when resolving the property from its name it first tries to look if the property is defined in the object itself, otherwise it looks at the properties in the prototype (delegation).

We can have arbitrary objects as prototypes for another object. Object has a method called create() that instantiate an object given a prototype:

We can then verify whether an object is prototype of another. This considers indirect prototype inheritance as well, so, since Object.prototype is prototype of a, Object.prototype is prototype of b too.

String, Array and Function

In javascript, strings, arrays and functions are objects! That’s why when we run the Object.prototype.toString function we get:

The difference is that while objects inherit from Object.prototype, strings, arrays and functions inherit from String.prototype, Array.prototype and Function.prototype respectively. Since these prototypes are objects, strings, arrays and functions inherit from Object.prototype as well:

Let’s take a closer look into functions. We can declare and call a function like this:

Let’s take a look at which properties are inherited from Function.prototype:

One of them is call, which we used above to invoke the function Object.prototype.toString(). It takes several arguments. It will call the function and bind the first argument to this within that function and the remaining of the arguments will be used as the actual arguments for the function. For example, if a function is defined as

We can invoke it by:

An alternative way to do that is using the function apply, where you pass an explicit argument to be bound to this, and the arguments in a array:

Having the parameter this is important so we can have stateful function, which enables us to simulate object oriented patterns.

We can simulate a class with functions and prototypes. The function represents a constructor of the class, which will have the same name as the function, and methods are defined by adding functions to the prototype:

To make new instances, we can invoke the function with the operator new:

To understand how the new operator works, we can implement a method that does the same:

Inheritance

We can simulate inheritance by instantiating an object and add properties to it:

Crockford [1] doesn’t like this pattern. His main argument is that if we forget the new keyword when instantiating we can cause unexpected behavior, because if no object is bound to this, it uses the global variable this:

His suggestion is not to use the class pattern at all, but rather work with prototypes inheritance directly.

Appendix: ES6 Classes

ECMAScript Edition 6 (ES6) is the next standard for the javascript language. The regular object-oriented class syntax is supported, but most browsers today run ES5 or lower.

We can already write ES6 syntax and use code transformers known as transpilers. Google has an open-source library called Traceur to transform ES6 syntax into ES5.

We can define a class representing a point:

It will generate this code: http://goo.gl/W7jFRU

References

• [1] Javascript: The Good Parts - Douglas Crockford
• [2] Yehuda Katz - Understanding Prototypes in Javascript
• [3] MDN - JavaScript reference
Tags: javascript prototype