JavaScript for C# Programmers: Object basics

Continuing the occasional series where I talk about writing JavaScript from a C# programmer's perspective.

This episode: the basics of objects in JavaScript.

If you'd read the previous episode of this series you'd have caught the fact that there is no class type in JavaScript, although — bizarre behavior warning — class is actually a keyword (it's just not used). Since in C# the class is the template from which you can create objects, what exactly is an object in JavaScript?

The simple answer is that it's a named hash map. Riiight. What's a...

Run-time properties with C#

Imagine this using C#: you create a class with an indexer, the index type is string, and the value is of type object:

  public class JsObjectLookalike {
    private Dictionary<string, object> data = new Dictionary<string, object>();
    public object this[string index] {
      get { return data[index]; }
      set { data[index] = value; }
    }
  }

It has no properties at all apart from the indexer, but you can create your own run-time properties as and when you wish. Here's an example of creating a person object, with an age property and a name property:

var person = new JsObjectLookalike();
person["age"] = 42;
person["name"] = "George";

The issue in C# is how to get the data out again. Usually, we'd have to deal with some ugly if conditions and casts galore, which is why we don't tend to use this kind of design. Certainly if the types of the properties you want to define at run-time are all strings, say, then this design becomes a possibility. Luckily, when I use Console.WriteLine(), this awkwardness gets temporarily hidden (ah, the magic of ToString()...):

Console.WriteLine(person["age"]);  // outputs 42
Console.WriteLine(person["name"]); // outputs George

So, in essence, a JavaScript object is a set of name/value pairs. The name is the key with which you get at the value, which can be any type at all. You can treat the name as an index in the same style as my C# code above, or, if the name is a valid identifier, by using the dot operator. Let's see how this is done.

Simple JavaScript objects

First create an empty object:

var person = {};

In this case, JavaScript uses braces to define the property values for a new object, but here we're saying the object contains no properties (the bit between the braces is empty). Note that there's no new in sight.

Let's add properties for age and name using the C# syntax above, and then read them back.

person["age"] = 42;
person["name"] = "George";
console.log(person["age"]);  // outputs 42
console.log(person["name"]); // outputs George

(Recall that I'm using Firebug in Firefox as my testbed. console.log() is a function injected by Firebug to display data to the Console panel.)

I could have equally easily done this instead, since both age and name are valid identifiers:

person.age = 42;
person.name = "George";
console.log(person.age);  // outputs 42
console.log(person.name); // outputs George

I can also mix and match the ways which I access the properties, provided the property name is a valid identifier:

person["height"] = 1.82;
console.log(person.height); // outputs 1.82

This shows that the same property is referenced whether I use the [] operator or the dot operator. Note, though that with the [] operator, the value in the square brackets can be any expression returning a string. (We'll use this ability to use a string expression below.) Take a look at this faintly weird example:

person[1] = "uh...";
console.log(person["1"]); // outputs uh...

Here what looks to be an array index, 1, is actually not. The number 1 gets coerced/converted at run-time into a string, "1", which is then used to name the property. You can't use the dot operator here, since 1 is not a legal identifier. (Hold that thought though for the next episode...)

You can create a fully populated object using a series of assignments to new properties as I've shown already, or you can use the JSON syntax:

var person = {
    age: 42,
    name: "George",
    height: 1.82,
    "is English": true
};

In case you'd forgotten: JSON stands for JavaScript Object Notation. In this example, I've shown that you can declare property names either as standard identifiers or as quoted strings if the names are not valid identifiers. This type of object declaration is also known as an object literal.

You can also declare properties that are also objects themselves:

var person = {
    age: 42,
    name: "George",
    height: 1.82,
    salary: {
        currency: "$",
        amount: 75000
    }
};

And then can use the properties of those nested objects just as you'd imagine:

console.log(person.name + " earns " + person.salary.currency + person.salary.amount);

If you want to change a property value, just do it in the same manner you always use:

person.age = 31;
person.name = "Joanna";

In fact, as you can see: there is no difference between creating a new property and setting its value, and modifying an existing property value. It's all the same. Unfortunately, this can really bite you if you manage to misspell the property name: you think you are setting an existing property, when in reality you are adding a brand new misspelled property. We'll talk about this in a future episode.

Objects are passed by reference

Not much more to say, really. Just like in C#, objects are reference types, not value types. They are accessed though a reference, and are passed around by reference.

Suppose we have the person object with a salary property as above. If we copy the salary property and then modify it, we will be changing the original salary too.

var georgeSalary = person.salary;
georgeSalary.amount = 80000;
console.log(person.salary.amount); // outputs 80000

Enumerating an object's properties

We now know how to create an object and add properties to it (we'll look at methods in a later episode). But how do we know which properties an object has? After all, in C# this is well-defined: we just look at the object's class. An object is an instance of a class and we can't change that class at run-time. Duh, end of story. But, just like my original example above where we used a Dictionary<string, object> and an indexer in order to be able to declare some run-time "properties", we can declare whatever properties we like for a JavaScript object.

JavaScript has a special for loop that will enumerate the properties of an object. Actually, to be precise, it's a for..in loop. It works like this:

var property;
for (property in person) {
    console.log(property + ": " + person[property]);
}

First I declare a variable, property, and then I enumerate the properties in person using the for..in statement. In the body of the for..in loop I merely output the property name and the property value using the [] operator. The result is this:

age: 42
name: George
height: 1.82
salary: [object Object]

It seems a bit of a shame that for..in can't be used in a C# foreach sense. Oh well.

Deleting a property

As we saw, adding a new property is easy, just reference it on the left hand side of an assignment. We can equally easily remove one using the delete operator:

delete person.height;

Not much more can be said about that, apart from saying that delete works on variables too, not just properties. It's a little weird from a C# viewpoint, but again think of the indexer and using it to create run-time properties.

The constructor function is Object. The typeof operator, applied to an object, returns the string value "object".

Next time we'll look at arrays, a special type of object.

Album cover for I've Been Expecting You Now playing:
Williams, Robbie - No Regrets
(from I've Been Expecting You)


Loading similar posts...   Loading links to posts on similar topics...

3 Responses

#1 Dew Drop - February 10, 2009 | Alvin Ashcraft's Morning Dew said...
10-Feb-09 8:17 AM

Pingback from Dew Drop - February 10, 2009 | Alvin Ashcraft's Morning Dew

#2 Dew Drop - February 10, 2009 | Alvin Ashcraft's Morning Dew said...
10-Feb-09 8:17 AM

Pingback from Dew Drop - February 10, 2009 | Alvin Ashcraft's Morning Dew

 avatar
#3 Sai Gudigundla said...
10-Feb-09 9:46 AM

These tutorials are very helpful. Keep 'em coming. You should write a book "Know C# ? then learn javascript"

Leave a response

Note: some MarkDown is allowed, but HTML is not. Expand to show what's available.

  •  Emphasize with italics: surround word with underscores _emphasis_
  •  Emphasize strongly: surround word with double-asterisks **strong**
  •  Link: surround text with square brackets, url with parentheses [text](url)
  •  Inline code: surround text with backticks `IEnumerable`
  •  Unordered list: start each line with an asterisk, space * an item
  •  Ordered list: start each line with a digit, period, space 1. an item
  •  Insert code block: start each line with four spaces
  •  Insert blockquote: start each line with right-angle-bracket, space > Now is the time...
Preview of response