JavaScript Methods¶
In this reading about JavaScript methods, we will be using methods for several kinds of objects, but not defining or implementing methods. We'll also talk about JS object literals as collections of data, but not yet in the sense of supporting method invocation.
Our first example will be to use the JavaScript Date
object, which is
built into the language.
Displaying the Date Dynamically¶
We can display the current date and time on a web page. For example:
If you reload this page, you'll notice that the date and time change appropriately.
Before we explain the JavaScript code that can do this, we need to
understand how time is represented in JavaScript. We begin by creating a
Date
object:
var dateObj2 = new Date();
As we've seen before, the keyword var
in var dateObj2
creates a new
variable named dateObj2
for storing a value. What we haven't seen
before is the keyword new
, which causes a JavaScript object to
be created. In this case, the object represents the current date and
time. JavaScript comes equipped with a few pre-defined object types like
Date
.
We can extract information from a Date
object by invoking
methods on it. The table below shows some of the important
methods that Date
objects understand. The elements of the
Value column are dynamically computed by evaluating the JavaScript
expressions in the Expression column, so reloading the page will
update these appropriately.
Expression | Value | Notes |
---|---|---|
dateObj2.getFullYear() | Full year | |
dateObj2.getYear() | Avoid this! Varies from browser to browser | |
dateObj2.getMonth() | 0=Jan, 1=Feb, ..., 11=Dec | |
dateObj2.getDate() | 1 to 31 | |
dateObj2.getDay() | 0=Sun, 1=Mon, ..., 6=Sat | |
dateObj2.getHours() | 0 to 23 | |
dateObj2.getMinutes() | 0 to 59 | |
dateObj2.getSeconds() | 0 to 59 | |
dateObj2.getTime() | Milliseconds since Jan 1, 1970 (the "epoch") |
Objects¶
Dates are examples of objects. In JavaScript, an object is a kind of value that has two important characteristics:
- state, which is given by what JavaScript calls properties.
- behaviors, which are specified by what JavaScript calls methods.
Both properties and methods are selected from an object using dot
notation. In the examples above, the variable dateObj2
contains a date object. The expression to the left of the dot in
dateObj2.getDate()
is a variable, dateObj2
, that
contains a date object. To the right of the dot is the name of the thing
we want to compute based on the object. In this case, we invoke the
getDate()
method, which returns the numerical day of the
month in a date object. (You can tell we're calling a method rather than
selecting a property by the presence of parentheses after the name.)
W3 Schools has a complete list of Date methods
Date Formatting¶
Now let's return to our date and time display. A date object contains a collection of information about the date and time, but for human-readability, we will need to format that data in some conventional way, using, for example, slashes and commas to separate the various numbers.
Here is JavaScript code that creates the correct string and pops up an alert box to display it. (Next time, we'll look at how to insert it into the document using the DOM). Click the blue button to run the code. You can also copy/paste it into a JS Console.
Let's examine the code. The first statement creates a Date
object representing the current date and time, and stores it in a variable
named dateObj
. Subsequent statements extract components of
this Date
object and piece them together.
As shown below, we could get by with only the single variable
dateObj
. Although the other variables are not strictly
necessary, they can help to make the code more readable. Note that
there's nothing special about naming the variable dateObj
.
We could have called it anything else, such as today
or
now
or fred
(but fred
would not be a good
name, since it wouldn't suggest the meaning or value of the data).
var dateObj = new Date();
var current_date = ( (dateObj.getMonth() + 1) + "/"
+ dateObj.getDate() + "/"
+ dateObj.getFullYear());
var current_time = ( dateObj.getHours() + ":"
+ dateObj.getMinutes() + ":"
+ dateObj.getSeconds());
Other Date Functions¶
The earlier date manipulation code was all numerical. That's partly
because JavaScript is used around the world, and they decided not to
have a built-in function to map month zero to January
when it
could just as easily have been Janvier (French), Enero (Spanish) or
Styczen (Polish).
Despite this, let's implement a simple function that maps month-numbers (ranging from 0 to 11) to English month-names. Try it out:
How would you print the name of the month 10 months from now?
Methods on Different Objects¶
We've used the example of dates to teach you about:
- Objects (encapsulations of data and methods to operate on it)
- methods (ways to extract or modify the data in an object)
Lots of other objects and methods exist in JavaScript, including on built-in types like numbers and strings. Later in the course, we'll learn how to define our own objects with their own custom methods.
Here's another method, this time on numbers, the
toFixed()
method. Note that you'll have to open the
JavaScript console to see the output, but using the console allows you to
see all the results at once. This reading will typically use console.log
rather than alert
from now on, so you might find it useful to keep the
JavaScript console open as you read this material. (You should read this
on a real computer, not a phone, so you actually have a JavaScript console
and can run the examples by clicking the "execute it" buttons.)
The toFixed()
method returns a string representation of the
number, with the number of decimal places given by the argument. It does
not change the value of the variable, as the last step shows.
Array Methods¶
Here are some handy methods for JavaScript
arrays. You
don't need to learn all of these now, though we will use some of them
later in the course. For now, it's sufficient to get a little practice
with using methods on different kinds of objects. Some of these
methods may remind you of ones you learned in Python (such as
.push()
and .pop()
.
Note that we've already learned two important array methods:
.map(callback)
and .forEach(callback)
, both of which take callback
functions as argument. Remember that a "callback function" is just a
function that is passed as an argument to a method.
push
adds a new element onto the end of an arraypop
removes and returns the last element of the arrayshift
removes the first element of an arrayunshift
adds an element onto the frontindexOf
searches for an element and returns its index (-1 if not found)splice
optionally removes some elements and optionally inserts someslice
copies an array
Try them out. Click the button and then look in the JS console for the result.
The forEach
method¶
Remember from our introduction to JavaScript that arrays also have a forEach
method that takes a
function as its argument, invoking the function for each element of
the array. The function is invoked with 3 arguments: the array item,
its index in the array, and the array. (You don't usually need the
last argument.)
Here's another example of that method.
JavaScript Object Literals¶
It's now time to return to talking about JavaScript Objects in general rather than just date objects.
As described earlier, in JavaScript, an object is a collection of data (properties and methods). This collection can be arbitrarily complex, including having other objects inside the containing object (much like a folder can contain other folders), but for now let's keep it simple. This is just like Python's dictionary data type.
An object is a collection of properties (also called keys) and values. We use the properties (keys) to look up the values. We'll use the terms properties and keys interchangeably
We'll ignore methods for now and focus on properties.
Let's be concrete. Imagine that we have an object to keep track of a user's info, including their name, year of graduation and whether they're going to the party. So, the three properties will be:
name
gradYear
going
We'll begin with a particular person, Alice, who is the class of 2019 and
is going to the party. We'll store all that info in a single object and
we'll store the object in a variable called person1
. We can
make a second object about another person, Betty.
Consider the following JavaScript code:
var person1 = {name: "Alice", gradYear: 2019, going: "yes"};
var person2 = {name: "Betty", gradYear: 2020, going: "no"};
Try copy/pasting that code into a JavaScript console. Look at the resulting objects:
> person1
> person2
Given those objects, how can we use them? We can use dot notation to read or update the data in the dictionaries:
console.log('Alice graduates in ',person1.gradYear);
console.log(person2.name, 'graduates in ',person2.gradYear);
// Betty has decided to go to the party after all:
person2.going = "yes";
// Betty took a leave and is graduating later:
person2.gradYear++;
JavaScript even has a cool console.dir
feature that breaks out all
the properties into separate, clickable things. This is particularly
useful for big, complicated objects, such as windows. Try it:
> console.dir(person1)
> console.dir(window)
Let's repeat those assignment statements
var person1 = {name: "Alice", gradYear: 2019, going: "yes"};
var person2 = {name: "Betty", gradYear: 2020, going: "no"};
The things on the right hand side are called object literals. The syntax of an object literal is an opening brace, a series of property/value pairs separated by commas, and a closing brace. Each property/value pair consists of a property (which follows the same rules as the names of variables), a colon, and a value. The value can be any JavaScript value, such as a number, string, or another object. Here's an abstract example like the above:
var personN = {prop1: value1, prop2: value2, prop3: value3};
Each of these object literals has three property/value pairs, but a JavaScript object can have any number of pairs, including none:
var empty_person = {};
Comparison with Python's Dictionaries¶
I said that JavaScript's objects are just like Python's dictionaries. Let's remind ourselves about how Python works with dictionaries. The following is Python code:
p1 = {'name': 'Alice', 'gradYear': 2019, 'going': 'no'}
p2 = {'name': 'Betty', 'gradYear': 2020, 'going': 'no'}
p1['going'] = 'yes'
print(p1['name'])
print(p1['going'])
print(p2['name'])
You're welcome to test that by copy/pasting it into a Python interpreter. Click the following to show/hide it:
Python 3.6.9 (default, Nov 11 2019, 11:24:16) >>> p1 = {'name': 'Alice', 'gradYear': 2019, 'going': 'no'} >>> p2 = {'name': 'Betty', 'gradYear': 2020, 'going': 'no'} >>> p1['going'] = 'yes' >>> print(p1['name']) Alice >>> print(p1['going']) yes >>> print(p2['name']) Betty >>>
Here's the same code in JavaScript. Note that I've made a couple of small changes, so that it looks even more like the Python syntax, namely I've put string quotes around the keys (properties). In Python, those quotation marks are required, but in JavaScript they are optional and are usually omitted.
p1 = {'name': 'Alice', 'gradYear': 2019, 'going': 'no'};
p2 = {'name': 'Betty', 'gradYear': 2020, 'going': 'no'};
p1['going'] = 'yes';
console.log(p1['name']);
console.log(p1['going']);
console.log(p2['name']);
Except for putting semi-colons at the end of the statements, and using
console.log()
instead of print()
the code is identical. So, if
you understand Python dictionaries, you understand JavaScript Objects.
Dot Notation¶
But what about the dot notation we learned earlier? Let's repeat our last JavaScript example, but with the dot notation as well as the square bracket and string literal notation:
p1 = {'name': 'Alice', 'gradYear': 2019, 'going': 'no'};
p1['going'] = 'yes';
console.log(p1['going']); // prints yes
console.log(p1.going); // prints yes
So, both p1['going']
and p1.going
print 'yes'
. The latter is a
shortcut that avoids a lot of punctuation.
But here's the crucial point: the shortcut only works when we know the
name of the property we want. (In this case, going
).
Most of the time, we will know the property we want in advance, so the dot notation is simple and easy.
Unknown Properties¶
When would you not know the name of the property? I can describe some situations, but maybe one you are already familiar with is a loop over all the properties, maybe in order to print them all.
Let's see that in Python first:
p1 = {'name': 'Alice', 'gradYear': 2019, 'going': 'no'}
for k in p1.keys():
print(p1[k])
The expression p1[k]
means to look up a key in the dictionary in
p1
where the name of the key is in the variable k
. So, it's a
variable rather than a constant like name
or gradYear
.
That Python code would print:
Alice
2019
no
In JavaScript, it's conceptually similar. There's a built-in object
called Object
that has a method keys
that will return an array of
all the keys (properties) in a object given as an argument to the
method. Then we can use the .forEach
method on the returned array to
print each value in the object. You can copy/paste the following into
a JS console to see it work:
var p1 = {'name': 'Alice', 'gradYear': 2019, 'going': 'no'};
var p1_keys = Object.keys(p1);
p1_keys.forEach(function (k) { console.log(p1[k])});
Note that p1_keys
holds an array of strings, specifically the keys
of the object p1
or ['name', 'gradYear', 'going']
.
The part to pay attention to is where we said p1[k]
, which is
exactly the same as the Python code. To repeat:
The expression p1[k]
means to look up a key in the dictionary in
p1
where the name of the key is in the variable k
. So, it's a
variable rather than a constant like name
or gradYear
.
The shortcut p1.name
works if and only if the name of the property
is a known constant.
Object Operations¶
Most of this section will be familiar to you if you remember how dictionaries work in Python, though I will often use the dot notation instead of the more cumbersome square bracket and string literal notation.
Given an object, there are a few things you might want to do to it:
- Retrieve the value associated with a property
- Modify the value associated with a property
- Add a new property/value pair
- Remove a property/value pair
Here are some specific examples of those operations with the person1
object. Copy/paste these into the JavaScript console to see them in
action.
var person1 = {name: "Alice", gradYear: 2019, going: "yes"};
// retrieving two values:
console.log(person1.name+" will graduate in "+person1.gradYear);
// modifying one value
person1.going = "no"; // something came up
// add a new property/value pair
person1.dorm = "Pom";
// retrieve two values:
console.log(person1.name+" lives in "+person1.dorm);
// remove a property/value pair
delete(person1.dorm);
You'll notice that the way we add a new property/value pair is identical to the way we modify an existing property/value pair: just an assignment statement. That's because JavaScript creates the property if necessary, and then updates the value.
In practice, removing a property/value pair is rarely done, so we really only need to remember two operations: getting and setting.
Here are two assignment statements that demonstrate both getting and setting. On the right hand side, we get a value out of one object and on the left hand side we set a value of an object.
var person1 = {name: "Alice", gradYear: 2019, going: "yes", dorm:"Pom"};
var person2 = {name: "Betty", gradYear: 2020, going: "no", dorm:"Caz"};
// Betty moves to Alice's dorm
person2.dorm = person1.dorm;
// Alice decides to delay her graduation by a year:
person1.gradYear = person1.gradYear + 1;
The syntax for getting and setting look the same: a variable, a dot, and a property.
The markers on a Google Map are another example of objects. Those markers
are objects with properties like lat
and lng
(latitude and longitude), along with other info. For example, something
like:
// Wellesley's location
var marker1 = {lng: 42.296612,lat: -71.301956};
Summary¶
Objects in JavaScript are general collections of data represented as key/value pairs. They can also be used to support methods to operate on the data. Later, we'll learn how to define methods.