Introduction to JavaScript for Python Users

Python and JavaScript are actually quite similar languages, despite a lot of superficial differences. In this reading, we'll learn JavaScript in light of your knowledge of Python, pointing out similarities and differences.

One major similarity is that they are both interpreted languages, in that when the code is run, each statement is checked one at a time and executed in this fashion. This is different from a compiled language, where the code is checked all at once by the compiler before it is run. CS 230 teaches Java, which is a compiled language. Think of translation of spoken languages: There are people who translate speech on the fly while it's being spoken. There are also people who will read an entire script beforehand, translate it in one sitting, then give the entire translated speech at once. Computer science-wise, the person who translates on the fly is like an interpreted language, while the person who translates in one sitting is like a compiled language.

On another note, you may think that JavaScript is similar to Java due to their names, but make no mistake, they are quite different. Historically, JavaScript was first named LiveScript, but it was re-named JavaScript in an attempt to boost its popularity (Java was new and exciting at the time). The official name of JavaScript is actually ECMAscript, but we will continue to refer to it as JavaScript.

In this reading, we'll be highlighting some important differences between JavaScript and Python.

Syntactic Differences

There are many syntactic differences between Python and JavaScript, and we'll review them in detail. But for now, let's just compare two functions that mean and do similar things, but look very different syntactically:

Python:

# this function is just an example; not particularly useful
def hello_world():
    print("Hello world!")
    print("I like CS 204")

JavaScript:

// this function is just an example; not particularly useful
function helloWorld() {
    // Similar to Python's print, but console.log is most often 
    // used in the browser rather than an environment like Canopy
    console.log("Hello world!"); 
    console.log("I like CS 204");
}

JavaScript uses curly braces to indicate code blocks, while Python uses indentation. Also, JavaScript uses semicolons to terminate statements, while python uses newlines.

Technically speaking, the following code works and does the same thing:

function helloWorld(){console.log("Hello world!");console.log("I like CS 204");}

But don't do that! Humans need to be able to read your code.

(In fact, sometimes JavaScript is minified before sending it to the browser, where all unnecessary characters are removed to speed up network transmission.)

The JavaScript Console

Here's a short aside about some practical stuff. Our JavaScript runs in the browser, and the developer tools includes a "console", which is similar to the Python interpreter (also called the Python shell or the Python Read-Eval-Print-Loop — the REPL).

It might look like this:

JavaScript console

If you type any Javascript expressions into the console, it will works as well:

JavaScript console

You can get to the console using Firefox on a Mac:

  • At the top bar, go to tools > web developer > Web Console, or
  • Command-Option-J

To print a value from JavaScript, we use console.log(val1, val2, ...); which prints to the browser console.

I strongly encourage you to open your JS console and try some of these snippets just by copy/pasting into the console. Here's a snippet to try:

let x = 3;
let y = 4;
let z = x + y;
console.log(x,y,z);

Here's what it looked like when I copy/pasted the snippet above into my JS console:

JS console example

The >> is the prompt from the JS console, indicating that it's ready for you to type something.

After copy/pasting the four lines above, I also typed in the names of each variable, and the JS console printed their values. The console colorized the code, with keywords in pink, variables in blue or purple, numbers in green and so forth. That can be helpful sometimes.

This is very like the Python REPL!

Naming Conventions

If we want to have a good name for a variable or a function, often that name involves more than one word. For example, "hello world" in the example above. Or maybe we have a program that keeps track of the "number of students" and a "student list". (If we just used one word, we might want to call both of those "students" and it wouldn't be clear what the meaning of the variable is.)

Unfortunately, Python and JavaScript have different conventions for these multi-word identifiers.

  • Python prefers snake_case, like number_of_students and list_of_students
  • JavaScript prefers camelCase, like numberOfStudents and listOfStudents

Note that these are just community conventions, not laws. Still, when you join a community, it's usually good to adopt its conventions. Or at least be aware.

So, how do I know these conventions? Here are two important style guides:

Because I code a lot in both Python and JavaScript, I often make mistakes, using the "wrong" convention. (I also have a personal preference for snake_case.) So, I won't be doctrinaire about this, but I encourage you to adopt the JavaScript community convention.

Comments

You probably noticed that Python uses one or more # characters to start an end-of-line comment (a comment that goes to the end of the line). JavaScript uses double slashes: //

JavaScript also has a syntax for multi-line comments; it's the same as Java's syntax:

/* this is a 
   very long comment
   with multiple lines
   */

Semi-colons

In JavaScript, statements end in a semi-colon, unlike Python. Python would declare and assign a variable like this:

x = 3

while JavaScript does it this way:

let x = 3;

However, unfortunately, the semi-colon is optional, and the browser is allowed to guess where to put them. It almost always guesses correctly, but not 100%. Because the bugs you get when it guesses incorrectly can be difficult to debug, best practice is to include the semi-colons (though there are some who argue otherwise). But sometimes they can be safely left off.

In my examples, I try always to use the best practice and include the semi-colons, but I occasionally miss one. There are also occasions where I think the semi-colon is needless syntactic clutter and I omit it on purpose.

JavaScript Datatypes

Values in JavaScript can be one of the following datatypes. You can click through to find out more technical details. (There are other types as well; this list is not exhaustive.) But we will see all of these this semester. This section introduces these types, but we'll learn more later.

  • null: The null object is similar to Python's None object. We won't worry about it a lot, but it will come up sometimes.
  • undefined: A variable that is not assigned a value has the value "undefined", which is different from null. You should almost always give a variable a value, but it's not required.
    
    let question = "What is the meaning of life?";
    let answer;  // value is undefined
    
  • Number: Numbers are straightforward. Examples like 7 or 3.14 are simple numeric literals. Python distinguishes integers from floating point values, but JavaScript doesn't typically distinguish them.
    
    let radius = 10;                             // an integer
    let area = 3.14 * radius * radius;           // floating point values
    let area_better = Math.pi * radius * radius; // use a pre-defined constant
    
  • String: A string is a sequence of characters enclosed by quotation marks, either single quotes or double quotes (but they must match). You may not break a string literal across a line boundary. The typical work-around is to use string concatenation like this:
    
    let quote = 'Now is the winter of our discontent' +
                "Made glorious summer by this sun of York";
    
  • Boolean: There are two literal values for true and false: true and false. Unlike Python, these are not capitalized.
  • Object: In JavaScript, objects play two roles. First, they are simple data structures of key/value pairs, virtually identical with Python's dictionaries. Second, they can also contain methods and become the essential building blocks of object-oriented programming, which we will discuss later this semester.
  • Function: Functions are standard in any programming language. In JavaScript, as in Python, functions are first class objects, which means that they are a kind of data, meaning that they can be stored in variables, returned from functions, passed into functions as arguments, and stored in data structures. Front-end web development makes extensive use of that feature, so we'll see it a lot this semester.
  • Array: Like Python, JavaScript has arrays. They are created with square brackets and commas, just as in Python. JavaScript doesn't have some of the same notations such as negative arguments to count from the end or getting slices by using colon notation.
    
    let primes = [2, 3, 5, 7, 11];
    
  • Date: A date object represents a moment in time (to the nearest millisecond). JavaScript has a built-in way to create date objects and to operate upon them. We'll discuss them next time, and we'll use them in at least one assignment and in the project.
    
    let rogerWinsAustralianOpen = new Date('29 Jan 2017 7:14 am'); // EST
    

    Internally, times are represented in Universal Coordinated Time (UTC) which is essentially Greenwich Mean Time, though you can typically work in local time. We won't be discussing timezones and such in this course; time is a complicated thing.

Variable Declarations

Python, we can create a variable just by assigning to a new variable name:

animal = "cat"

JavaScript requires a keyword when creating (declaring) an new variable. Historically, that keyword was var:

var animal = "cat";

JavaScript also has two new keywords let for local variables and const for values that will not change. In fact, it's quite common to use const unless you are definitely going to change the value later. So in the code below, many professional coders would use const instead of let, since all of the variables are assigned once and not modified. This is a useful signal to the reader. Nevertheless, I'll use let in most cases.

function taxAndTip(bill, taxRate) {
    const TIP_RATE = 0.20;  // tip 20%
    const MAX_RATE = 0.25;
    if( taxRate > MAX_RATE ) {
       console.log('This violates usury laws!');
    } else {
       let tip = bill * TIP_RATE;
       let tax = bill * taxRate;
       let total = bill + tax + tip;
       return total;
    }
}

You're encouraged to copy/paste that function into the JS console and try it out with a few arguments. If the bill is 100 and the taxRate is 10 percent (0.10), the total payment should be 100 + 10 + 20 or 130; right? Try it and see.

tax and tip JS console example

The new keywords, let and const are preferred, except for global variables, which we'll talk about later.

When you use any of these keywords, you are declaring a new variable. Without the keyword, you are updating an existing variable. Be clear and explicit about that: you should know when you are creating (declaring) a new variable, so signal that to the reader by using let or const.

We'll return to these keywords later.

Conditionals

In Python, indentation is crucial to conditionals. In JavaScript, we use braces to demark the beginning and end of blocks of code, and indentation just as helpful information to the reader.

Python:


# Python conditionals

if age >= 18:
    print "You can vote"

    if age >= 21 or (age >=18 and !currentlyInUS):
        print "You can get a drink"
elif age >= 16:
    print "You can get your license"
elif age == 15:
    print "You can get your permit"
else:
    print "No special privileges yet"

JavaScript:

// JS conditionals. Notice the logical expressions in
// parentheses, such as (age >= 18)

if (age >= 18) {
    console.log("You can vote");

    if (age >= 21 || (age >= 18 && !currentlyInUS)) {
        console.log("You can get a drink");
    }
} else if (age >= 16) {
    console.log("You can get your license");
} else if (age == 15) {
    console.log("You can get your permit");
} else {
    console.log("No special privileges yet");
}

Here's a quick summary of the differences for conditionals and booleans:

Python: and or elif True False if True:
# Do something
JavaScript: && || else if true false if (true) {
// Do something
}

Note that there's no elif in JavaScript. You chain another if statement on, using else if. It's only a three extra characters to type.

Functions

As you've seen earlier, JavaScript functions are defined using the key word function instead of def.

function name(parameter1, parameter2, parameter3) {
    return value
}

Unlike Python, JavaScript is very flexible about the arguments. Any extra arguments are ignored, and there is no error for missing arguments (though your code might not work properly).

function sub(a,b) {
    return a-b;
}

sub(5,4,3); // returns 1, the 3 is ignored
sub(5,4);   // returns 1
sub(5);     // the subtraction will yield NaN, for Not a Number

Built-in Functions

Here are some useful built-in functions and their Python equivalent. Don't worry about memorizing these. We'll learn them with practice.

Python JavaScript Description
print(x) console.log(x) prints a value to the console
no equivalent alert(x) pops up a window displaying the value
input(str) prompt(str) Not an exact comparison, but the Python version gives a text prompt, while the JavaScript version gives a pop-up prompt in the browser.
len(a) a.length Returns length of a string or array
str(a) String(a) or a.toString() Converts type to string
max(a, b) Math.max(a, b) Returns maximum of two numbers
min(a, b) Math.min(a, b) Returns minimum of two numbers
random.randint(a,b) Math.random() Returns a random number. Python returns a random number from a to b inclusive, while JavaScript returns a random number from 0 to 1. You can write a function to specify what you need, as detailed in this documentation. You need to import the random library for Python, while JavaScript's Math object is already built-in.

String Concatenation

As with Python, you can concatenate two strings with the + operator. However, in JavaScript, the values don't have to be strings. If they aren't, they are converted to strings. So the following is quite common:

let ans = 3+4;
alert('the answer is '+ans);

The first + is actual addition; the second concatenates the string 'the answer is' with the value in ans (presumably 7), converting the 7 to a string, and pops up a window with the result.

Gotchas!

An important fact is that you can add numbers and strings together in JavaScript, which is unlike Python. JavaScript turns the number into a string, concatenates the two together, and returns the resulting string.

let notFour = 2 + "2";         // Gets "22"
let ourClass = "CS" + 204;     // Gets  "CS204"
let piString = 3.14 + "1519";  // Gets "3.141519"

But the pitfall is that if you're not careful, you can get results you didn't expect. The following code seems to add the numbers x and y, but it doesn't:

let x = prompt('first value to add');
let y = prompt('second value to add');
let z = x + y;
alert('result is '+z);

Because prompt always returns a string, both x and y are strings, and so z is the concatenation of the two strings. Probably not what you intended at all!

If you want to change your string into a number, there are the functions parseInt() and parseFloat(). The first tries to extract an integer from a string and the latter tries to extract a floating point number.

let three = parseInt("3.14");  // Gets 3
let pi = parseFloat("3.14");   // Gets 3.14
let x = parseInt("five");      // Gets NaN (the Not A Number value)

Thus, the earlier example can be corrected to:

let x = parseFloat(prompt('first value to add'));
let y = parseFloat(prompt('second value to add'));
let z = x + y;
alert('result is '+z);

Arrays

As we saw above, JavaScript arrays are very similar to Python arrays. They have a .length property that gives the length, similar to Python's len() function.

let primes = [2, 3, 5, 7, 11];
let pl = primes.length;  // 5
alert(pl+' primes');  // 5 primes

What we often want to do with arrays is get and set values at different places. That's done exactly the same way as in Python. Remember, arrays start the indexing at zero:

let myClasses = ["CS 204", "ENG 103", "CAMS 240", "ECON 101"];
alert("my last class is "+myClasses[3]);
// replace ENG 103 with AFR 105
myClasses[1] = "AFT 105";

As always, you're encouraged to try these code snippets out by copy/pasting into the JS Console.

Loops

Usually, once you know about arrays/lists in a language, you next learn loops, so that you can do some code for every element of the array or list. JavaScript does have loops, but I'm not going to teach those to you, at least not now.

Instead, we will use methods that operate on arrays and take functions as arguments.

Syntax Remarks

So far, JavaScript is just like Python: the concepts are the same (variables, datatypes, functions, conditionals, etc.). The syntax is different, very different, but actually it's Python that's the odd one. JavaScript has a syntax that is derived from an ancient computer language called C, and C is also an ancestor of C++, Java, C#, Go, Swift, R, Rust, and many others, all of which are used today (as well as C itself). So, when you feel frustrated with the JavaScript syntax, remember that it's the "normal" language; Python is the oddity.

(Which is not to say that I don't like Python's syntax; I do. JavaScript's syntax is okay, too. And, yes, I get confused between the two languages from time to time.)

Advanced Functions

In this course, we will be using functions in a more sophisticated way than you did in CS 111. (You can do these same ideas in Java and Python, too, but you probably didn't.) This will take a lot of getting used do, and you'll make plenty of mistakes, but that's to be expected. Let's start with a few ideas.

First Class Functions

JavaScript functions are first-class values, so they can be stored in variables, passed into functions and returned as values of functions, and so forth. See the Wikipedia entry on First-Class Functions if you'd like to learn more.

What does that mean? Let's get there in a few steps, starting with anonymous functions. That's a function that is a bunch of code, but without a name.

Anonymous Functions

Functions without function names are called anonymous functions. In Python, you use lambda to create anonymous functions, but most versions of CS 111 don't cover lambda, so we'll omit lambda here. However, you may have seen lambda in the context of a key function for sorting, like this:

# python code
student_tuples = [
    ('john', 'A', 15),
    ('jane', 'B', 12),
    ('dave', 'B', 10)
]
sorted( student_tuples, key=lambda student: student[2]) # sort by age

To create an anonymous function in JavaScript, simply use the keyword function without the function name. This syntax is called a function literal or a function expression, and so you would typically put it on the right hand side of an assignment (like other expressions) or put it in the parentheses of a function call. Here's an example:

let f = function (a, b) {return a * b};

This is a screen shot from when I typed that into my browser console. Feel free to do the same in your browser and see what it looks like for you. (For the last part, I clicked on the gray triangle in the blue block to "toggle" open the output.)

screenshot of function f

How would we use such a function? Believe it or not, we use the variable f in the same way we use a function name, by following it with parentheses and arguments:

> f(3,4);
12

Here's another screenshot:

screenshot of f(3,4)

The reason this is important is that it allows us to think about defining a function and then giving the function to some other function to execute. (That's what we did with the key function in the example of Python's sorted function, above: the lambda function was passed to sorted to be used in the sorting algorithm.)

Sorting is complicated, but let's consider a simpler example: doing something with every element of an array.

The MAP method on Arrays

There are methods to operate on each element of an array, particularly the map method. For example, if I have a list of numbers, and I want a list of their squares, I can do this:

function square(x) {
    return x*x;
}

let nums = [1, 2, 3, 4];
let squares = nums.map(square); 
alert(squares);  // [1, 4, 9, 16]

This is complicated and very new, conceptually, so let's take it one step at a time.

First, we defined a square function in the normal way. Nothing surprising there, and we can use it in the normal way:

>> square(3);
9

Second, we created an array of numbers. Again, this isn't anything new; it's just like Python and similar to Java:

let nums = [1, 2, 3, 4];

The last step is the weird one. Because nums is an array, it has a method called map. The map method takes one argument, which has to be a function. That is, we have to pass a function to map to do all the work.

In fact, this function can't be just any function: it has to be a function that works on one argument. So, we couldn't use our function f above, because that requires two arguments. But square is a function of one argument, so we can pass it to the map method, which then gives us back a new array of the results:

let squares = nums.map(square);

And squares looks like [1, 4, 9, 16].

Passing Anonymous Functions

Here's the same code as above, but this time using an anonymous function instead of defining square:

let nums = [1, 2, 3, 4];
let squares = nums.map(function (x) { return x*x }); 
alert(squares); // [1, 4, 9, 16]

The nice thing about using the anonymous function literal as the argument to the .map() method is that all the code is right there; you don't have to look elsewhere for the function code.

Another nice thing about using an anonymous function is that if I have a weird function, I don't have to think of a name for it, I just have to code it. Here's a function that triples a number and adds 1:

let nums = [1, 2, 3, 4];
let vals = nums.map(function (x) { return 3*x+1; });

The result, vals, will contain [ 4, 7, 10, 13 ]. Copy/paste the code above into your browser console if you'd like.

Named Versus Anonymous Functions

A reasonable question is why you'd use an anonymous function instead of a named function. So, let's start with why you'd use a named function.

Named functions are very useful when you want to

  • define the function once, and then
  • call it from many places using the name

The name allows you to refer to it from somewhere else, and a good name means that the code is more readable and understandable. These are all good things.

This is similar to why we might give names to values (by putting them in variables). For example, the quadratic formula uses a value twice to find two roots:

let shared = Math.sqrt(b*b - 4*a*c);
let root1 = (-1*b + shared)/(2*a);
let root2 = (-1*b - shared)/(2*a);

But you might agree that if you only use a value once, maybe it's not worth giving a name to it. For example, you'd probably write the Pythagorean Theorem like this:

let hypotenuse = Math.sqrt(a*a + b*b);

and not like this:

let a2 = a*a;
let b2 = b*b;
let c2 = a2 + b2;
let hypotenuse = Math.sqrt(c2);

Similarly, anonymous functions are most useful when you only need the function once. So, rather than name it and then call it from somewhere else, you just write the code right where you need it.

Very often, the place where you need the function is as the argument to another function. Since giving a function to the browser is an important thing in web programming, we use anonymous functions all the time.

The forEach Method

A method similar to .map is forEach(), which takes a function of up to three arguments: the item, its index in the array, and the array itself. In practice, the third argument is often ignored, and we will omit it here. (Remember that JavaScript allows you to invoke a function with more arguments than it's declared to take. The extra arguments are just ignored. Here, if we supply an anonymous function that takes only two arguments, it means we aren't interested in the third argument — the array.)

The following prints out the contents of an array, using an anonymous function, and ignoring the third argument.

let primes = [2, 3, 5, 7, 11];
primes.forEach(function (item, index) {
     console.log(index+': '+item);
});

Again, try it! Here's what it did for me:

printing an array of primes using forEach

(The final gray "undefined" in the screenshot is the return value of the forEach method. The forEach method is used for what is does, not for what it returns. It always returns undefined.)

Here's another example: we want to convert every element of an array of strings to uppercase. We can use forEach with a three-argument function, assigning the new value to the current array element:

let quote = ['be', 'the', 'change', 'you', 'want'];
quote.forEach(function (str, index, arr) { arr[index] = str.toUpperCase(); });
console.log(quote);  // ['BE', 'THE', 'CHANGE', 'YOU', 'WANT']

What this code does to ask forEach to apply the anonymous function (we can think of it as the uppercasing function) to each array element in turn. JS invokes our function with the array element (str), its index in the array (index), and the array itself (arr). Our function replaces the array element with the uppercase version of the string.

If we don't want to modify the array, we typically omit the third argument. So the following examples use alert to tell us something about each element of the array, in which case we need only the element (str) or the element and its index (index):

let quote = ['be', 'the', 'change', 'you', 'want'];
quote.forEach(function (str) { alert(str.toUpperCase()); });
quote.forEach(function (str, index) { alert(index+': '+str.toUpperCase()); });

(Try it!)

We will use the forEach method in an upcoming version of Ottergram, and we will use the idea of passing functions as arguments many times in this course.

You can use named or anonymous functions; they are nearly (but not quite) interchangeable. Here's the same code with a named function:

function printItemAndIndex(item, index) {
    console.log(index+': '+item);
}

let primes = [2, 3, 5, 7, 11];
primes.forEach(printItemAndIndex);

Ottergram will use an anonymous function in a way that is not easily replaced with a named function, but we'll cross that bridge when we get to it. For now, understand that anonymous functions are useful and not that weird. I urge you to try to get used to them. Modern web development has lots of anonymous functions.

We'll see how anonymous functions can be used in more practical applications later.

forEach versus Loops

You're probably thinking that in Python or Java you would use a for loop to do the kinds of things we did using forEach. Indeed, JavaScript has loops very similar to every other language. However, we will not be using those in this course, for two important reasons:

  • forEach allows us to use a named function if one is handy or convenient, and
  • using forEach gives us practice with passing functions as arguments, which is an important skill in modern programming.

If it helps, you can think of the anonymous function as the body of the for loop: it's executed once for each item of the array.

Callback Functions

When a function f is passed as an argument to a function/method, g, the function f is sometimes described as a callback function, since g will be calling f. For example, look at the MDN description of forEach

Passing Functions in Web Applications

The reason that understanding functions as first-class values and passing them as arguments is important is because of how we will be using functions in web programming. A lot of what we will do will be defining a function and then passing it to the browser, for the browser to invoke. This is similar to passing square to the map function.

To use the terminology of the previous section, web programming often involves writing callback functions.

Functions as Return Values

We've passed functions as arguments to other functions. We can also return functions from functions. Here's an example:

function addRand(max) {
    let rand = Math.floor(max*Math.random());
    return function (n) { return n+rand; };
}

In action:

x = [1, 2, 3, 4, 5];
f1 = addRand(5);
f2 = addRand(100);

A few examples:

f1(1);
f1(2);
y1 = x.map(f1);
y2 = x.map(f2);

So, the return values remember the value of rand that they computed and they use it consistently, every time.

Arrow Functions

A relatively new feature of JavaScript is the ability to define arrow functions, which are even more succinct but also have some technical differences that we'll get into later. Arrow functions can only be one expression, which is returned.

primes = [2, 3, 5, 7 ];
prime_squares = primes.map( x => x*x );
alert(prime_squares); // [ 4, 9, 25, 49 ]
neg_primes = primes.map( x => -1*x );
alert(neg_primes);  // [ -2, -3, -5, -7 ]

I don't find the extra typing for normal functions to be burdensome, so I haven't gone whole hog for arrow functions, but there are a few times when they are really nice. You should add them to your toolkit.

!! sorting

Summary

We've covered a lot of topics. Here's a brief reminder of our whirlwind tour:

  • Indentation is not significant (but do it anyhow)
  • braces and semi-colons are the important syntactic sugar
  • The JS community prefers camelCase over snake_case.
  • comments are // or /* and */
  • datatypes
    • null (like None)
    • undefined
    • Number (integers and floating point)
    • String
    • Boolean (true and false, uncapitalized)
    • Object: we'll talk a lot more later
    • Function: first-class. Can be named or anonymous
    • Array: let primes = [2, 3, 5, 7, 11 ];
    • Date: a particular date and time. More later
  • variable declarations. Always declare a variable when you create it.
    • let for variables that will or might change
    • const for variables that won't or shouldn't
  • conditionals: if( boolean_expr ) { then_block } else { else_block }
  • boolean operators:
    • && for and: both expressions are true
    • || for or: either expression is true (or both)
  • functions: function name(arg1, arg2) { function_body }
  • built-in functions:
    • console.log(arg1,arg2) prints the arguments to the console
    • alert(arg) pops up a window that shows the argument
    • prompt(str) pops up a window that requests a string from the user. Shows the str explaining what is wanted
    • array.length returns the length of the given array
    • x.toString() converts the value of x to a string and returns it
    • Math.max(a,b) returns the larger of two numbers
    • Math.min(a,b) returns the smaller of two numbers
    • Math.random() returns a random number between 0 and 1
  • string concatenation is done with the + operator. Works on non-strings, which can be a trap: x+y is not necessarily add.
  • Arrays. indexed from zero, just like in Python and Java. Uses square bracket notation. favs[0] = primes[3];
  • Loops: JavaScript has them, but we won't be using them.
  • Functions are first class values. That means
    • you can pass them as arguments to functions (callback functions)
    • you can store them in variables and other data structures
    • you can return them as values from functions
  • Functions can be anonymous:
    • function (arg1, arg2) { function_body }
    • typically stored in a local variable or immediately passed as an argument
  • Arrays have a .map(func) method
    • it takes a function as an argument
    • the function takes one argument, which will be an element of the array
    • the function should return a value
    • .map collects all the return values and returns an new array containing the values
    • example: let doubles = numbers.map( function(x) { return 2*x; } );
  • Arrays have a .forEach(func) method
    • it takes a function of 1, 2 or 3 arguments
    • func(elt) just the element
    • func(elt, index) the element and its index
    • func(elt, index, array) the above and the array. (this is rare)
    • the argument function is invoked with the item, its index and the array
    • the .forEach() method returns no value
  • JavaScript has arrow functions that can be convenient:
    • syntax can be (arg1) => expr
    • example: let doubles = numbers.map( (x) => 2*x );
    • the arrow function in this form returns the expression
    • syntax can also be (arg1) => { function_body }
    • Like regular functions, they can take more than one argument.
    • example: numbers.forEach( (elt,idx) => { console.log(idx+': '+elt) })

Whew! That's a lot. But remember, much of this is based on ideas you know (variables, conditionals, functions, arrays) just in a different form.

But there are certainly new ideas:

  • functions as first class values
  • anonmymous functions
  • methods that take functions as arguments
  • arrow functions (though you don't have to use these if you'd rather not)