Object Programming and Object-Oriented Programming

© 18 February, 2013, Martin Rinehart

Object-oriented programming (OOP), a set of techniques born in Simula and Smalltalk, became the mainstream paradigm after Stroustrup/Bell Labs introduced C++ (1983), a better C, specifically improved with the introduction of OOP. As C++ grew to become a dominant language (and a very large one, too) Java was introduced (1995). It adopted the C++ OOP model, substituting interfaces for multiple inheritance. Java grew to replace Cobol (1959!) as the dominant language for commercial data processing. The C++/Java OOP model, although it was arguably a step backward from Smalltalk, is now called "classical."

JavaScript (also 1995) introduced a new object programming model, which can be called "object programming" (OP). To understand the difference, we begin with a partial definition of "object" as it is used in both. An object starts as a collection of properties, each property having a key and a value. Keys, in JavaScript, are limited to strings and are called "names." In classical OOP the names are the subset of strings acceptable as variable identifiers. In both, the possible values are as simple as a boolean or as general as another object. (In JavaScript, functions are objects and therefore can be property values.)

The essential difference between OOP and OP is that in the former the programmer works with the values of properties. In the latter, the programmer works with properties, both names and values, and with the objects themselves, adding and/or removing properties as needed.

Class Definitions

In classical OOP, one begins with a module called a "constructor." The constructor defines the properties (names and types) that are part of a "class" of objects. Each member of the class, called an "instance" of the class, will have the same set of properties.

In object programming the code can add or remove properties at will, so the initial definition of a list of properties is vastly diminished in importance. JavaScript allows any function to be used as a constructor. By convention, not requirement, JavaScript constructors (only) start with a capital letter. The "new" keyword, in JavaScript, is an operator that creates an empty object (given the reference this within the constructor), assigns a reference to the constructor in the object's prototype, available as this.constructor, and assigns this.constructor.prototype as the prototype object of this. As in OOP, the programmer writes code as needed to further equip this with an initial set of properties. The constructor then returns the this reference to the object.

In the classical OOP model, constructors define classes, including defining the properties that are members of each instance of the class. In the JavaScript OP model, constructors serve to define the initial set of properties of an instance, and to link instances to the "prototype" that is used to store instance methods. The prototype also refers to its own prototype in a chain that can be used to implement classical inheritance. (Inheritance, in JavaScript, is little used compared to inheritance in classical OOP.)

JavaScript Has No Classes?

Some developers (who really should know better!) criticize JavaScript for not having classes. This is foolishness born of ignorance. It would be like JavaScript developers criticizing classical OOP for having no prototype chains. (The latter mistake is seldom made since most JavaScript developers have some background in classical OOP.)

A "class" in classical OOP starts with a constructor function. In JavaScript, the equivalent job is done the same way, by a constructor function. A class may also include properties (including functions) of its own (in Java: "class statics"). In JavaScript these would be attached directly to the constructor function for the same result.

Critical to the OOP model is that "instance methods" (functions that can be called by any instance object) are stored in the class. (It would be extremely wasteful to store duplicate copies of each method with each object instance.) In JavaScript, instance methods are stored in the constructor function's "prototype" property.

In the classical model, functions are not objects and therefore cannot be fitted out with properties. JavaScript allows properties attached to functions which provides a perfectly good alternative to OOP classes.

In general, the JavaScript constructor plus its prototype property allow the same facilities as the classical OOP class provides for instance objects. The ability to add additional properties to the constructor provides the facilities of "class statics" in Java's OOP. The ability to add still more properties at run time gives JavaScript's object programming far more power than the frozen-at-compile-time classes of classical OOP.

Object Programming

In object programming, working with property values is done just as it is in classical OOP. You can write, for example:

foo.bar = expression;

That line evaluates the expression and assigns the result to the bar property of the foo object in both OOP and OP. In JavaScript you could write the same line this way:

foo[ 'bar' ] = expression;

That does exactly the same thing, substituting subscript notation for classical dot notation. This gets interesting when you consider this:

var propname = name_expression;
foo[ propname ] = expression;

The above evaluates the name_expression and uses it as the name of the property for which the next result will be the value. If the property exists, its value is replaced (as in OOP). If the property does not exist, it is created. (As is uncommon in OOP. Hybrid languages, such as Python, allow dynamic creation of object properties. This capability is fundamental to object programming.)

More OP

The page Object Programming Examples provides additional object programming examples. It shows how a very simple function can "add" two objects together (creating one object with the properties of both added objects). It shows how this can be used in styling DOM elements on an HTML page.

Another example on that page shows a routine that reverses keys and values. If you assume that JavaScript's objects are programmed to optimize retrieval of values given property names, it follows that retrieval of property names given values will be less efficient. Reversing keys and values rectifies this problem:

person[ 'name' ] = 'Martin'; // typical

// after reversing:

person[ 'Martin' ] // value is 'name'

The OOP programmer first meeting JavaScript does not find the old, familiar classes. The OOP class functionality is all there, but the programmer has to learn a new model. (And the programmer has to learn a small bit of the functional programming capabilities of JavaScript, such as assigning properties to functions.)

The OP programmer will not find the OOP toolkit to be adequately stocked. To match JavaScript's built-in capabilities the programmer needs to abandon C++ OOP, for example, and drag in library routines to manage hash table dictionaries, then build a solution from the library structures. As you can imagine, this does not improve the readability and maintainability of the resulting program.

Inheritance

Inheritance in classical OOP is achieved through class hierarchies. These are not necessary if object programming (OP) capabilities are present. (On this site, see JavaScript Inheritance Methods Compared for a comparison of solutions that create OOP-style classes in JavaScript.)

Recreating classical inheritance in JavaScript is not necessary. This author concluded that it was easier to meet JavaScript on its own, prototypal terms. JavaScript guru Douglas Crockford reached the same conclusion, calling his classical inheritance code "a mistake."

It is, however, a serious tribute to the power of JavaScript's OP model that you can easily bend it into the C++/Java class-based model. Writing a prototypal inheritance system in C++ or Java would certainly take far more than the 60 lines (or less) it takes to emulate classical OOP in JavaScript.

The classical and prototypal inheritance models achieve the same goals. The programmer used to one,however, will need to do some fresh learning to master the other.

Object Programming Defined

The OOP model combines object instances, sets of key/value pairs, with a class structure that provides a routine to create instances, storage for instance methods and other services. This definition of object programming should provide significantly more power:

Note that by this definition, the JavaScript OP model is incomplete as it does not allow direct modification of property names. (It takes a three-line utility function to modify a property name. A direct approach to modifying the name would be preferable and it could avoid a possibly expensive object copy.)

Conclusion

Object programming (OP), as in JavaScript, is substantially more powerful than object-oriented programming (OOP), as in C++ and Java. The essential difference is that OOP allows the programmer to manipulate values in an object's key/value pairs. while the OP model allows the programmer to manipulate both keys and values. Additionally, the OP programmer can manipulate the structure that is equivalent to the OOP class at runtime (in addition to defining the structure at compile time).


Feedback: MartinRinehart at gmail dot com

# # #