This notebook is to help you learn the basics of JavaScript data structures, particularly lists and dictionaries. You have hopefully seen a little bit of these two data structures in 2308, as list
or vector
and hash_map
. Python and JavaScript both make these structures very easy to work with, and web development depends heavily on them.
This is a JavaScript translation of the Python Data Structures notebook.
JavaScript provides a variety of basic data types that support common operations.
You can write numbers and strings:
var a_num = 5
var a_str = 'puppy'
Note that, unlike Python, we declare our variables with var
. JavaScript requires you to declare your variables (like C++), but does not give them types (unlike C++).
Our notebook will also happily print the value of the last expression:
a_str
You can do math, of course:
a_num * 3
And manipulate strings:
a_str + ' dog'
JavaScript can coerce data to other types, unlike Python. While the following Python code:
'puppy' + 5
will fail, JavaScript is just fine with it:
a_str + 5
If one of the operands of +
is a string, it will convert the other to a string and concatenate them.
JavaScript does not have a good, built-in equivalent to Python's string formatting.
We can find out the length of a string:
a_str.length
In Python, ==
respects type: a string is never equal to a number.
In JavaScript, ==
will convert the objects to be of a compatible type and then compare them.
1 == 1
'1' == 1
0 == false
1 == null
0 == null
1 == true
Wonky. To avoid that, use ===
(strict comparison) instead of ==
:
0 === false
There is a corresponding !==
operator.
We can write functions in JavaScript:
function add5(n) {
return n + 5
}
add5(10)
The function is declared with function
, and its parameters are just named (without types), as they are in Python.
To help us avoid certain errors in JavaScript, it is useful to enable strict mode for all our JavaScript functions:
function fib(n) {
'use strict'; // this enables strict mode
// also, comments work like C++
var v1 = 1, v2 = 1;
var i;
for (i = 2; i < n; i++) {
var tmp = v2;
v2 = v2 + v1;
v1 = tmp;
}
return v2;
}
fib(5)
fib(10)
Strict mode turns things like undeclared variables into errors, and makes a few other improvements. It is not supported by all JavaScript engines, but modern browsers support it.
Lists, which JavaScript calls arrays, do what they say on the tin: they store a list of things. Think like a grocery list, or a to-do list: it is a sequence of items.
For example, the following code creates a new list and assigns it to a variable called beatles
:
var beatles = ['John', 'Paul', 'George', 'Ringo']
We can see that the list has 4 items by examining its length
:
beatles.length
JavaScript arrays look a lot like C++ arrays, in that we can get a specific item:
beatles[0]
and we can reassign one:
beatles[2] = 'Albert'
If we want to loop over the elements of an array, the most straightforward way to do it is with a C++-style counter loop:
var i;
for (var i = 0; i < beatles.length; i++) {
console.log(beatles[i])
}
(The undefined
is just because the last expression — our for
loop — does not return any value, but the JavaScript notebook support doesn't suppress JavaScript undefined
like it does Python None
.)
We can also loop using JavaScript's forEach
method, and an anonymous function. This is the way that is most analagous to Python's for
loop, and is often what I use:
beatles.forEach(function(beatle) {
console.log(beatle)
})
This code creates a little function that prints out its argument, and passes that function as an object to the forEach
method of the JavaScript array. Like Python, but unlike C++, functions are objects that can be passed around like any other object. This is a common pattern in JavaScript.
ES6, the latest version of the JavaScript standard, introduces a for
loop that works like Python's:
for (var beatle of beatles) {
console.log(beatle)
}
Unfortunately, ES6 support is not sufficiently widespread to allow us to take advantage of this.
Like Python lists, but unlike C++ arrays, JavaScript arrays allow us to add values:
var results = []
results.length
OK, an empty list. Let's add things to it:
results.push('wumpus')
JavaScript uses push
instead of Python's append
. We can see that the results
list now has length 1:
results.length
And see the element there:
results[0]
There isn't a good way to delete arbitrary elements of an array. However, we can delete the first element with shift
, or the last with pop
.
results.shift()
results.length
We can populate it in a loop:
for (var i = 0; i < beatles.length; i++) {
results.push("Beatle number " + i + " is " + beatles[i]);
}
results
JavaScript objects work like Python dictionaries or other languages' hash tables and maps. They let us associate arbitrary properties by name, and put data in them. The syntax is even very similar.
var liz_the_first = {
'name': 'Elizabeth I',
'region': 'England',
'birth_date': '1533-09-07',
'death_date': '1603-03-24',
'coronation_date': '1559-01-15'
}
The squiggly braces denote an object, and the keys and values are separated by colons (:
).
Finding out how many things are in it is a little trickier. There is a method, Object.keys
, that gives us an array of the keys in the object:
Object.keys(liz_the_first)
We can get its length:
Object.keys(liz_the_first).length
We can get individual items:
liz_the_first['name']
Since name
is a valid JavaScript identifier, we can also just access it as a property:
liz_the_first.name
We can also assign new values:
liz_the_first.mother = 'Anne Boleyn'
liz_the_first['family'] = 'Tudor'
Now, if we want to iterate over the keys, we can do this:
for (var k in liz_the_first) {
console.log(k + ': ' + liz_the_first[k])
}
This kind of a for
loop only works for iterating over object keys.
We can also delete information, and assign arbitrary types of values:
delete liz_the_first.region
liz_the_first.regions = ['England', 'Ireland']
liz_the_first