Everything is a property of an object in JavaScript

I am bumping this up because I think it's important. This was originally published on my blog on July 8th, 2008!

jQuery in Action coverThe book jQuery in Action is no light reading. It's not the type of book you can read in a couple of sittings. I started reading my copy several months ago. It might easily become one of the best three-to-five computer books I'll read in my life. I am reading the excellent appendix now, titled: JavaScript that you need to know but might not! Boy did I totally not! I will dump what I am learning here in two installments.

Everything is a property of an object in JavaScript

In JavaScript, everything is a property of an object — or else it is disembodied, floating in deep Space, unreferenced. Or I should say: Everything is assigned to a property of some object.

Let’s begin by examining sample code. I would like to create a new object in JavaScript. I go about doing it in the following fashion:

/* Using the new operator with the Object constructor. */
var car = new Object();
/* Populating the empty object with properties. */
car.make = 'Nissan';
car.model = 'Altima';
car.year = 1992;
car.purchased = new Date(1998, 8, 21);

In client-side web JavaScript, an object is an unordered collection of properties. In client-side web JavaScript, an object has no methods. A property has a name and it has a value, and the value is always an object. It can be an Object object, it can be a String object, a Number object... or it can be a Function object.

I am already using object literals to define my car object. I could be anal and redefine my object by being a lot more verbose in the following fashion:

var car = new Object();
car.make = new String('Nissan');
car.model = new String('Altima');
car.year = new Number(1992);
car.purchased = new Date(1998, 8, 21);

We can easily nest an Object object within an Object object like so:

var car = new Object();
car.make = new String('Nissan');
car.model = new String('Altima');
car.year = new Number(1992);
car.purchased = new Date(1998, 8, 21);
var owner = new Object();
owner.name = new String('Caroline Schnapp');
owner.occupation = new String('occupational hazardist');
// The car owner is an Object object.
car.owner = owner;

Then we can refer to the car owner's name like so:

var myName = car.owner.name;

So a JavaScript object is an unordered collection of properties, or named values. It is much like a hash in Ruby.

We can use what's called object literals to define our object in a less verbose fashion. The following code snippet will define the exact same car object but this time using object literals all the way — except for the Date object, that is:

var car = {
  make: 'Nissan',
  model: 'Altima',
  year: 1992,
  purchased: new Date(1998, 8, 21),
  owner: {
    name: 'Caroline Schnapp',
    occupation: 'occupational hazardist'
  }
};

Using the dot notation is only one way to access the value of a property, one that's recognized by programmers who have come to OO-programming from other languages like C++ — programmers like myself, in other words. There is a more general way of accessing a value that will work for any sort of property name. It would work for a property name that contains a space, a dot, or even for a property name that is computed! So here's the dot notation and the more general way of reading a property value:

myObject.propertyName == myObject['propertyName']

Hence, the following console.log() statements will output to your Firebug console the same property value:

console.log(car.owner.name);
console.log(car['owner']['name']);
console.log(car['ow'+'ner'].name);
var n = 'name';
console.log(car['owner'][n]);

A function is always a property of an object

The following two statements are perfectly equivalent:

/* Ubiquitous way of declaring a function */
function outputText(text) { 
  console.log(text); 
}
/* What this hides is that I just assigned a Function instance
 * to the window 'outputText' property...
 */
window.outputText = new Function('text', 'console.log(text);');

So a function is really a Function object, or Function instance.

It doesn't have a name. Does not. It has a list of arguments (could be zero, one or more arguments), and it has a body, that is, some code to execute.

Really, 'outputText' is not the name of any function; 'outputText' is a property of the window object, to which we are assigning a Function instance.

Yes, we defined a global-scope function, so it got assigned to a property of the predefined window object. Top-level variables are properties of the window object, as well. Remember: Everything is a property of an object in JavaScript.

After such declaration, we can use the outputText() function like so:

outputText('hello');
/* Or, same thing: */
window.outputText('hello');

We can assign that function object to a new property like so:

var create = outputText;
/* Or, same thing: */
window.create = outputText;
/* Or, same thing: */
window.create = window.outputText;

To reuse the function object like so:

window.create('hi');
/* Or, same thing: */
create('hi');
The following are all equivalent for defining so-called “variables”:
var someText = String('Let me be');
window.someText = String('Let me be');
someText = String('Let me be');
// Using object literal now, that is, shorthand
var someText = 'Let me be';
window.someText = 'Let me be';
someText = 'Let me be';

A shorthand version for defining a Function instance

We defined a Function instance and assigned it to a top-level window property. But we can also assign Function instances to properties of run-of-the-mill Object objects. Let's extend our car object with a utility function that provides the name of its owner:

var car = {
  make: 'Nissan',
  model: 'Altima',
  year: 1992,
  purchased: new Date(1998, 8, 21),
  owner: {
    name: 'Caroline Schnapp',
    occupation: 'occupational hazardist'
  },
  whoOwnsMe: function() { return this.owner.name; }
};

That was sneaky of me, I just introduced you to a concise way of defining a Function instance called a Function literal. Number objects have their object literal shorthand definition. String objects have their object literal shorthand definition. And so do Function objects! The following four statements are perfectly equivalent:

/* Ubiquitous way of declaring a function */
function outputText(text) { 
  console.log(text); 
}
/* What this hides is that I just assigned a Function instance
 * to the window 'outputText' property...
 */
window.outputText = new Function('text', 'console.log(text);'); 
/* And now, ladies and gentlement,
 * the shorthand version.
 */
window.outputText = function(text) {console.log(text)};
/* or, same thing... */
outputText = function(text) {console.log(text)};

So it looks like all object types in JavaScript (Object, Function, Number, String, to name a few) have their own object literal way of being defined.

Object literals

I can use my utility Function this way:

var myName = car.whoOwnsMe();
/* which is nothing else than... */
window.myName = car.whoOwnsMe();

Function instances can be assigned to properties — and they can also be used as parameters. Assigned they can be, but they have no name. They only have arguments and a body, that's it and all. The following drawing shows the divide that exists between the Object that references a Function instance, and the Function instance that's referenced. The function acts as a method of the Object, yes, you could say that, but it really is not a method, because it does not belong to the Object per say. It lives outside of it.

A Function instance lives outside of whoever is referencing it.

You want proof that our no-name Function instance does not belong to our car object? Let's assign a String instance to car.whoOwnsMe right now.

car.whoOwnsMe = 'The god of cars';

The car.whoOwnsMe property used to point to a Function instance...? Not anymore. We can reassign to the car.whoOwnsMe property whatever value our whims dictate, such as: another Function instance, a String instance, a Number instance, whatevah and whenever.

What happens when we use car.whoOwnsMe as if it was still pointing to a function? We get this error in our Firebug console: TypeError: car.whoOwnsMe is not a function. Try it out:

/* Making my property 'reference' a String object. */
car.whoOwnsMe = 'The god of cars';
/* Using the property as IF it was still referencing a function. */
var myName = car.whoOwnsMe();
/* You should get a JavaScript error with the last statement.
/* And now using the property as we should... */
var hisName = car.whoOwnsMe;
/* hisName is now equal to 'The god of cars'. */
/* The End */

A Function instance can act as if it is a method

It is all an act.

But it is just some Function instance temporarily or permanently assigned to a named property of some object. It is a property among many. It is not really a method. It can act as if but it is not.

It's all an act. Do not be fooled.

So let's recap: an Object object is an unordered collection of named properties. To these properties are assigned values. These values are object instances of different types. These types can be: Object, Function, String, Number. In the life span of an object, we can re-assign new values to the object's properties — although common sense would suggest that we avoid this.

A Function instance is a stand-alone ranger of JavaScript space. Many different properties can point to him/her. What I mean here is that we can assign to many different properties belonging to many different objects a same Function instance. That's called code reuse. And within the body of that Function instance, that's been assigned to all who want it, the keyword this will point to the current object the Function is assigned to.