Object Properties

In JavaScript, an object is a collection of property-value pairs. We look up a value using a property. You can think of this as like Python's dictionaries.

Python Rectangles

Here's an example using Python dictionaries to represent a rectangle (with properties like width and height and area).

r1 = {'height': 10, 'width': 20}
r1['area'] = r1['height']*r1['width']
print(r1['area'])

Feel free to copy/paste that into your favorite Python interpreter; it works and prints 200.

JavaScript Rectangles

Here's the same example, this time using JavaScript syntax:

r1 = {'height': 10, 'width': 20};
r1['area'] = r1['height']*r1['width'];
console.log(r1['area']);

You can copy/paste this code into the JS console in your favorite web browser to test it. It also works and prints 200.

A Syntactic Shortcut

So far, the two syntaxes look completely identical, and you are welcome to use Python-style syntax with JavaScript objects in CS 204. However, JavaScript provides a shortcut that is completely standard and ubiquitous, so you should learn it.

Unfortunately, that shortcut is sometimes confusing to many students, and explaining the distinction requires a bit of terminology and some unfortunate abstractions, but take a deep breath and come with me for a while. After the necessary abstractions, I'll have a detailed example that will make things more concrete.

JavaScript Rectangles with Shortcut

First, let's re-do the rectangle example using the shortcut syntax:

r2 = {'height': 10, 'width': 20};
r2.area = r2.height*r2.width;
console.log(r2['area']);

It works exactly the same way.

The Syntactic Shortcut

So, let's look abstractly at the syntactic difference, focussing on the second statement of each example:

r1['area'] = r1['height']*r1['width'];
r2.area = r2.height*r2.width;

In a nutshell, the two syntaxes each uses a property name but the property name can be either

  • a string literal in square brackets, or
  • typed after a dot without quotation marks

As long as you stick to examples like these rectangles, the shortcut is simple and easy to understand. Fortunately, almost every situation we will have in CS 204 (and in computing in general) is like these, so if you feel comfortable with the two syntaxes so far, you are in good shape.

Complexities

Now it's time for me to make you uncomfortable, by pushing on this a bit. Let's take the tiniest bit of code you can imagine:

x.y

The expression x.y has two one-letter names in it, but the two names are treated very differently. The x is a variable, but the y is a literal.

Literals

What's a literal? A literal is a value that the programmer types into the code. Here's an example:

var a = b + 2;

We all know what this means. The right hand side is an expression that adds two values. What two values? One value is whatever is in the variable b; so we actually don't know what value it is. The other value is 2 because that value is literally in the program code. So, a literal is a value that is right in the code, not stored in a variable someplace. We know what it is by reading the code.

So, let's return to our tiniest object expression: x.y

We said that the two names are treated differently:

The x is a variable, so that means that the object we are working with is in that storage location. Is it a date object? A rectangle object? Some other kind of object? We would have to read and understand the program to know. It's very similar to the b variable in the a=b+2 example.

The y is a literal, so we know that we are accessing the y property of the object in x. The name of the property is not in a variable; the name is literally in the program code.

The same is true of the following non-shortcut (long-cut) syntax: x['y'] We know that we are accessing the y property of the object, because we can see a string literal in the program code. That string is known and fixed.

Non-Literal Properties

With the long-cut syntax that Python and JavaScript share, the property name is given with a string literal, but we could use a variable. It takes more lines of code, but the meaning is equivalent.

Let's make either the width or the height of our rectangle bigger. Specifically, let's double it. Here it is in Python:

p = 'width'
r1[p] = 2 * r1[p]
print(r1)

In JavaScript, it looks exactly the same, except for the semi-colons at the ends of the lines:

p = 'width';
r1[p] = 2 * r1[p];
console.log(r1);

Now, I want to isolate just the assignment statement that modifies the object:

r1[p] = 2 * r1[p];

Here, the code does not show what property is being modified. We have to know or remember that p is a variable that stores the name of the property being modified. It is not the name of the property.

Extended Example

Images fall into two categories based on their shape: portrait and landscape. A portrait image is just one that is taller than it is wide, while a landscape is wider than it is tall. Here are two examples (the red boxes are square):

eiffel tower
lincoln memorial on $5 bill

An image gallery often puts every image into a uniform box, possibly square, to make the layout easy. Unthinkingly reshaping the images of the Eiffel Tower and the Lincoln Memorial would look grotesque:

eiffel tower
lincoln memorial on $5 bill

So, we want to re-shape each image while retaining its aspect ratio and scaling its bigger dimension to be, say, 200px (the size of the boxes above). To retain the aspect ratio, we scale both dimensions by the same factor. The result would look like this:

eiffel tower
lincoln memorial on $5 bill

The following JavaScript function takes a rectangle object as its argument (the same kind of rectangle object we saw at the beginning of this reading). It modifies the object so that its larger dimension is 200 and the smaller dimension is multiplied by the same factor.

function resize(rect) {
    var dim;
    if( rect.width < rect.height ) {
         // portrait mode, so limiting dim is height
         dim = 'height';
    } else {
         // landscape mode
         dim = 'width';
    }
    var factor = 200 / rect[dim];
    rect.width = factor * rect.width;
    rect.height = factor * rect.height;
    return rect;
}

Here it is in action, using two examples where the dimensions are simple numbers, so the scaling factor will be pretty easy. (Actually, the scaling factor happens to be 2 in each case, so it's like our earlier example of doubling the size of a rectangle.)

> land1 = {width: 100, height: 50};
> resize(land1);
{width: 200, height: 100}
> port1 = {width: 50, height: 100};
> resize(port1);
{width: 100, height: 200}

Let's focus on just a few lines from the function definition:

    var factor = 200 / rect[dim];
    rect.width = factor * rect.width;
    rect.height = factor * rect.height;

Notice that the first line uses square brackets and a variable, so we genuinely don't know what property is being used to compute the scaling factor. We know it will be either the width or the height, but we don't know which. We have to use the square bracket notation since the property name is in a variable.

On the next two lines, we scale each dimension by the same factor. Here, it's fine to use the literal values.

Shortcut != Longcut

If you've followed all this, you can distinguish three cases:

  1. x.y The y property of the object in variable x
  2. x['y'] The y property of the object in variable x; same meaning as the first case, but longer syntax.
  3. x[y] Some property of the object in variable x; the name of the property is in the variable y

Methods

JavaScript conventionally uses the shortcut notation when invoking methods:

var d = new Date();
var m = d.getMonth();
alert('The month is '+m);

On the right hand side of the second line, we are invoking a method of the date object, but we are also accessing (and then invoking) the getMonth property of the object stored in variable d.

The dot notation to invoke object methods is also used by Python, Java and many other languages.

Method examples in Python:

array.append()
array.pop()
str.upper()
str.split()

Summary

The shortcut syntax of JavaScript object notation with a dot and a literal is simpler and less cumbersome to type and to read than the general notation with square brackets and a string literal. It's used all the time in JavaScript programming, as well as programming in Python and Java.