Another mutable, composite data type.
Unlike arrays, whose elements are ordered and indexed with numbers, objects have “properties” which are indexed with string names.
Literal objects are written enclosed in curly braces: {}
s.
Within the {}
s are zero or more pairs of property names and values.
Each pair consists of a property name, a colon, and the value.
Pairs are separated by commas.
let point = { 'x': 10, 'y': 20 }
Makes an object with two properties 'x'
and 'y'
.
The value of the 'x'
property is 10.
The value of the 'y'
property is 20.
[]
operatorSyntactic sugar is anything in the syntax of a programming language that makes it easier or more convenient to read or write without actually enabling anything that couldn’t be done with a more verbose syntax.
When a property name follows the rules for Javascript variables we can omit the quotation marks around the property name in the object syntax:
let point = { x: 10, y: 20 };
And we can access the property with a dot followed by the property name not in quotes.
Objects are useful whenever we want to collect related values into a tidy package that stays together.
We want to write a function drawConnectedPoints
that draws a bunch of line segments through a series of points passed as an argument, or aguments, to the function.
How can we represent the points we want to pass to the function?
// xs is a list of x-coordinates;
// ys is a parallel list of y-coordinates
const drawConnectedPoints = (xs, ys) => {
for (let i = 0; i < xs.length - 1; i++) {
const x = xs[i];
const y = ys[i]
const nextX = xs[i + 1];
const nextY = ys[i + 1];
drawLine(x, y, nextX, nextY, 'black');
}
};
Parallel lists are a drag because everything you do with them you have to do in parallel.
Also it’s not always obvious that those two lists are supposed to be used together.
// points is a list of x/y coordinates represented
// as two-element lists.
const drawConnectedPoints = (points) => {
for (let i = 0; i < points.length - 1; i++) {
const p = points[i];
const next = points[i + 1];
drawLine(p[0], p[1], next[0], next[1], 'black');
}
};
This is better than parallel lists and in this case it’s not terrible since points only have two values and by mathematical convention they’re always listed as x and then y.
But with more complicated data it can be confusing to remember which value is supposed to be at index 0
and which at 1
and beyond.
// points is a list of point objects,
// each with an x and y coordinate.
const drawConnectedPoints = (points) => {
for (let i = 0; i < points.length - 1; i++) {
const p = points[i];
const next = points[i + 1];
drawLine(p.x, p.y, next.x, next.y, 'black');
}
};
This solves the problems of both the two earlier versions.
Even better would be if drawLine
was changed to take point objects rather than loose x and y values.
Then this could look like this:
// Assume drawLine accepts point objects as arguments.
const drawConnectedPoints = (points) => {
for (let i = 0; i < points.length - 1; i++) {
drawLine(points[i], points[i + 1], 'black');
}
};
Like the elements of an array, properties of objects are assignable places.
point['x'] = 200;
point.y = 300;
const p1 = { x: 10, y: 20 };
const p2 = p1;
p1
and p2
are different names for the same object. If you do this:
p1.x = 100;
it changes the property on that object so p2.x
is now 100 as well.
(Note also that const
only applies to the variable; it doesn’t stop us from changing the objects’ properties.)
Object can be compared with ===
and !==
.
But two objects with the same properties and same values are not ===
to each other.
p1 === { x: 100, y: 20 } ⟹ false
But because p1
and p2
are different names for the same object:
p1 === p2 ⟹ true
const p = { x: 10, y: 20 }; // Note: x starts at 10
const foo = (point) => {
point.x = 100; // Change value of x property
return point;
};
const p2 = foo(p)
Inside the function the argument point
is just another name for the object as we assigned to p
. Changing point.x
changes the object we know as p
.
p.x ⟹ 100
p2 === p ⟹ true
There’s more to say about objects including how to create objects that have their own methods in addition to their own properties but we’re going to save that for next semester.