Introduction to JavaScript

JavaScript is probably the most popular programming language in the world.


JavaScript, the language:

JavaScript was originally named Mocha and written by Brendan Eich in 10 days in May of 1995. The name was changed to LiveScript in September, 1995, and became JavaScript sometime after that.

Although over 20 years old, JavaScript is still an evolving language. A lot of the code in the wild, and a lot of the code you see online and in books, is quite old and may not follow modern best practices. This is just the way the world is. Get over it.

Also see:

Getting Started

Here’s your first JavaScript program (a one-liner, of course):

console.log("Hello, world.");

This script consists of
one statement which is a call to
the function that is the value of
the property named log of
the property named console of
the global object.

There are at least five ways to run JavaScript code:

  1. Bookmarklet. Type "javascript:" followed by the program into your web browser’s location field.
  2. Runner. Use the JavaScript Runner, JSFiddle, JS Bin,, or CodePen.
  3. Shell (REPL). Use the developer console that comes with your web browser or the REPL in Node.js.
  4. Embedded in HTML. You can write JavaScript code directly inside of an HTML document:
    <!doctype html>
        <title>A Greeting</title>
        <p>My first JavaScript program:</p>
          console.log("Hello, World.");

    but this is frowned upon; better is to put it in a separate file and reference the script by filename:

    <!doctype html>
        <meta charset="UTF-8"/>
        <title>JavaScript Temperature Converter</title>
        <h1>Temperature Conversion</h1>
          <input type="text" id="temperature">
          <input type="button" id="f_to_c" value="F to C">
          <input type="button" id="c_to_f" value="C to F">
        <p id="result"></p>
        <script src="temperature.js"></script>
    function report(celsius, fahrenheit) {
      document.getElementById("result").innerHTML = `${celsius}°C = ${fahrenheit}°F`;
    document.getElementById("f_to_c").onclick = () => {
      const f = document.getElementById("temperature").value;
      report((f - 32) / 1.8, f);
    document.getElementById("c_to_f").onclick = () => {
      const c = document.getElementById("temperature").value;
      report(c, 1.8 * c + 32);


    JavaScript programs can run not only in web browsers, but also virtual worlds, Adobe Photoshop, and other environments.

    Exercise: What other host environments have JavaScript programs run in?
  5. On the command line!. Run the program with Node.js. For example:

    const limit = +process.argv[2];
    for (let x = 1, i = 0; i <= limit; i += 1) {
      console.log(`2^${i} = ${x}`);
      x += x;
    $ node powers.js 5
    2^0 = 1
    2^1 = 2
    2^2 = 4
    2^3 = 8
    2^4 = 16
    2^5 = 32

Basic Concepts

The language architecture is rather simple:

That’s it. Things that seem like basic concepts, like functions, arrays, and regular expressions are just kinds of objects, though syntactically sugared.

Data Types

There are 7 types:

TypeValues of the Type
UndefinedOnly one value: undefined. Means “I don’t know,” “I don’t care”, or “None of your business.”
NullOnly one value: null. Means “no value.”
BooleanOnly two values: true and false.
NumberThe IEEE 754 floating point values. Values that are integers can be expressed in binary, octal, decimal, or hex; non-integers must be expressed in decimal. Examples:
  • 8
  • 7.23342
  • 6.02e23
  • 0xff3e
  • 0b11010100001010
  • 0o237
  • Infinity
  • NaN
StringSequences of zero or more UTF-16 code units. Examples:
  • "hello"
  • "She said 'I don’t think so 😎'... (╯°□°)╯︵ ┻━┻)"
  • 'x = "4"'
  • "abc\tdef\"\r\nghi\n🏄‍♀️🏀\n"
  • "Olé"
  • "Ol\xe9"
  • 'Will I?\u043d\u0435\u0442\u263a'
  • `The sum of ${x} and ${y} is probably ${x + y}`
Strings are immutable. Only backtick-delimited literals can span lines and support string interpolation.
SymbolUnique things. Every time you create a symbol, you get a new thing, different from all other symbols. Examples:
  • Symbol()
  • Symbol('dog')
  • Symbol('dog') // different from the one above
ObjectEverything that isn’t one of the above six types. Examples:
  • {}
  • {latitude: 74.2, longitude: -153.11}
  • [true, true, {last: false, value: 'okay'}, [0, 0, 2]]
  • new Set([5, 1, 2])
  • new Date(2000, 12, 31)
  • (x, y) => x * x + y * y
  • /Boo+m!?/gi

Some common operations on numbers:

Some common operations on strings:

These work on numbers and strings:

These work on any value:

Weak Typing

Usually, if an operator doesn’t get operands of the right type, it does conversions to get arguments of the right types. This means JavaScript is weakly typed. In a strongly typed language, on the other hand, operands of the wrong type generate an error.

When a boolean is expected:

When a number is expected:

When a string is expected:

A value that is false or would be converted to false is called falsy. All other values are truthy. (I did not make up those names.)


Undefined, Null, Boolean, Number, String, and Symbol are called primitive types. Object is a reference type, meaning object values are references. Objects have properties which are key-value pairs. Access the properties with either dot or square bracket notation. You can even delete properties.

let x = {};
x.age = 17;
x.height = 65.3;
let score = x.age * x["height"];
let z = {age: 30, color: "red", total: 3};
z.last = true;
let rat = {triple: {a: 4, b: undefined, c: {4: null}}, 7: "stuff"};
delete z.age;

Notice how the values of primitives are ”stored directly” while the values of objects are the pointers, not the objects themselves:


Exercise: Show in pictures, the evolution of a system through the following:
   let a = {x: 3, y: 5};
   let b = {x: 3, y: 5};
   let c = a;
   console.log(a === b);
   console.log(a === c);
   a.x = 10;

There’s some convenient syntax surrounding objects that is good to know:

let x = 10;
let c = {x, y: 3}        // x is the same as x:x, so {x: 10, y: 3}
let o = {a: 5, b: 4, c}; // {a: 5, b: 4, c: {x: 10, y: 3}}
let {b, c: {y}} = o;     // This is called destructuring. Now b is 4 and y is 3


Every object in JavaScript has a prototype. When looking up properties, the prototype chain is searched. Objects created with the { } syntax all get the same built-in prototype (more on this later), but you can alternatively set the prototype when the object is created, with Object.create:

let protoCircle = {x: 0, y: 0, radius: 1, color: "black"};
let c1 = Object.create(protoCircle);
c1.x = 4;
c1.color = "green"; // Now c1.y === 0 and c1.radius === 1


Here $c1$ has two own properties: x and color. It has two inherited properties: y and radius.

Prototypes are very useful when creating a bunch of objects that look or behave similarly:



An array is an object constructed with square brackets or the new Array syntax. It has a length property as well as non-negative integer properties.

let a = [];
let b = [1, 5, 25];
let c = new Array();                      // Same as []         (DON'T DO THIS)
c = new Array(4, 5, 6);                   // Same as [4, 5, 6]  (DON'T DO THIS)
c = new Array(10);                        // 10 cells, all undefined.
let [d, e, f] = [a.length, b.length, a];  // d===0, e===3, f===[] (destructuring)

let g = [1, true, [1,2], {x:5, y:6}, "Hi"];
let h = {triple: {a:4, b:"dog", c:[1,null]}, 7: "stuff"};
let i = [h.triple.a, h[7]];

g[1];          // true
g[2][0];       // 1
g.length;      // 5
g[10] = 100;   // Makes g[5] through g[9] undefined
g.length;      // 11
g.length = 2;  // Now g is just [1, true]
Exercise: Experiment with arrays. Can we get to the third element of array dogs by saying dogs.2 or dogs["2"]? Or is dogs[2] the only way? What about dogs."2" or let x=2; dogs.x?
Exercise: Experiment some more with arrays. Does let x = ["dog"] define a one element array? What if we create a three-element array and try to print the value of its 12th element? What if we create a three-element array and set the value of its 12th element.
Exercise: What’s going on here?
   let a = new Array(3);
   a[0] = 1;
   a[1] = "hello";
   a[2] = a;

Here are some array operations:

// Construction
const a = [300, 900, 200, 400, 300, 700];
const b = [500, 300];
const c = Array.of(95, 33, 'dog', false); // [95, 33, 'dog', false]
const d = Array.from('dog');              // ['d', 'o', 'g']
const e = [5, ...b, -10]                  // [5, 500, 300, -10] (see the splat?)
const f = [b, ...b]                       // [[500, 300], 500, 300]

// Tests
Array.isArray(['x', true, 3]);            // true
Array.isArray({0: 'x', 1: true, 2: 3});   // false

// Accessors (these do not change their operands)
a.includes(400)      // true
a.includes(7)        // false
a.indexOf(300)       // 0
a.lastIndexOf(300)   // 4
a.indexOf(2500)      // -1
a.slice(2, 5)        // [200, 400, 300]
a.slice()            // makes a shallow copy!
a.concat(b)          // [300, 900, 200, 400, 300, 700, 500, 300]
a.join('--')         // "300--900--200--400--300--700"
a.toString()         // '300,900,200,400,300,700'

// Mutators
a.push(3)            // returns 7, a is now [300, 900, 200, 400, 300, 700, 3]
a.pop()              // returns 3, a is now [300, 900, 200, 400, 300, 700]
a.unshift(8)         // returns 7, a is now [ 8, 300, 900, 200, 400, 300, 700 ]
a.shift()            // returns 8, a is now [300, 900, 200, 400, 300, 700]
a.reverse()          // a is now [ 700, 300, 400, 200, 900, 300 ]
a.sort()             // a is now [ 200, 300, 300, 400, 700, 900 ]
a.fill(9)            // a is now [ 9, 9, 9, 9, 9, 9 ]
e.splice(1, 2, 90, 70, 200, 6, 17);
                     // At position 1, remove 2 elements, and insert the others
                     // e is now [ 5, 90, 70, 200, 6, 17, -10 ]
e.copyWithin(1, 4, 6)
                     // shallow copy elements at positions [4, 6) to position 1
                     // e is now [ 5, 6, 17, 200, 6, 17, -10 ]
Exercise: Experiment with slice. Show that you can use it for inserting elements only, deleting elements only, or replacing elements only.
Exercise: Experiment with copyWithin. What if the target range overlaps the source range? What if (any of) the indexes are out of bounds? How are negative indexes handled?

You will sometimes see Array.from when programming in the web browser. Things like NodeLists and HTMLCollections look like arrays but they aren’t; use Array.from to turn them into real arrays if you need to do such things.


Functions are either arrow functions or non-arrow functions. Here are some arrow functions in action:

(x => x * 2 + 1)(20)                                    // evaluates to 42
const square = x => x * x;                              // can also use let or var
const now = () => new Date();
let hypotenuse = (x, y) => (Math.sqrt(x * x + y * y))
hypotenuse(3, -4)                                       // evaluates to 5

Non-arrow function values use the function keyword, the Function constructor, or are created in a function declaration. When inside an object, you can leave off the function word:

function successor (x) {
  return x + 1;
const sum = function (x,y) {return x + y;}
const predecessor = new Function("x", "return x - 1;"); // Don’t actually use this

const x = {
  f: (a) => a * 3,                  // arrow function
  g: function (a) {return a * 3;},  // NOT an arrow function
  h(a) {return a * 3;}              // NOT an arrow function

A function value is fully first-class in JavaScript meaning:

Furthermore a function is an object so:

Functions that are passed and returned are called higher order functions. This should be no big deal. We had higher order functions in the 1950s in Lisp, but it took many decades for the whole world to realize how awesome this was.

const plusSix = x => x + 6;
const squared = x => x * x;
const twice = (f, x) => f(f(x));
twice(plusSix, 5);                           // 17
twice(squared, 4);                           // 256
const compose = (f, g) => (x => g(f(x)));
const squareThenPlusSix = compose(squared, plusSix);
squareThenPlusSix(10);                       // 106
compose(plusSix, squared)(5);                // 121
`twice expects ${twice.length} arguments`;   // 'twice expects 2 arguments'


Passing an argument to a parameter is just like assignment. Nothing more, nothing less. But there are interesting things:


Variables declared with var are local to the innermost enclosing function. When declared with const or let, they are local to the innermost enclosing block.

Variables are visible within their scope (this includes blocks and functions nested within that scope) and are invisible outside:

var a = 1;
let b = 2;
// c, d, e, and f are not in scope here
function example() {
  console.log(c); // undefined
  // If we tried to use d here, it would throw a ReferenceError
  var c = 3;
  let d = 4;
  console.log(e); // undefined
  // If we tried to use f here, it would throw a ReferenceError
  if (true) {
    var e = 5;
    let f = 6;
    console.log(a, b, c, d, e, f);
  console.log(e); // 5
  // f out of scope, using it would throw a ReferenceError
// Only a and b are in scope here; c, d, e and f are no longer in scope

Did you read that example carefully? Note that using a let or const variable in its scope but before the declaration throws a ReferenceError. Doing that with a var variable just gives you undefined.

Here’s a major ramification of function scope versus block scope:

let a = [];
for (var i = 0; i < 10; i++) { a[i] = () => i; }
a[3]();                                              // 10, GRRRRR
for (let i = 0; i < 10; i++) { a[i] = () => i; }
a[3]();                                              // 3, YES I EXPECTED THAT
Exercise: Study that example.

The var keyword is obsolete. Never use it. You should know how it works though, because you might see it in other people’s code.


When an inner function is sent outside its enclosing function, it is called a closure (because the outer variables are retained and “close over” the function). Closures are very popular in JavaScript because local variables are one of the very few ways to do information hiding.

You will often see code like this:

const nextFib = (() => {
  let [a, b] = [0, 1];
  return () => {
    [a, b] = [b, a + b];
    return a;

nextFib();    // 1
nextFib();    // 1
nextFib();    // 2
nextFib();    // 3
nextFib();    // 5
nextFib();    // 8


There’s another way to do that previous example. It’s a little weirder. Learn both ways.

function* fibGenerator() {
  let [a, b] = [0, 1];
  while (true) {
    [a, b] = [b, a + b];
    yield a;

const fib = fibGenerator();;    // { value: 1, done: false };    // { value: 1, done: false };    // { value: 2, done: false };    // { value: 3, done: false };    // { value: 5, done: false };    // { value: 8, done: false }


The expression this evaluates to different things based on what the heck is going on at run time.

  1. If used in a top-level statement outside of any function, or at the top-level statement in a function called as a global function, it refers the global object.
    a = 3;
    this.a;                      // 3
    this.a = 2;
    a;                           // 2
    function f() {this.a = 10}
    a;                           // 10
  2. If used in a function f that was called call to a function made with one of the function methods apply, call, or bind, the value for this was “passed in” somehow. (Note: there are other places in JavaScript where you can “pass in” a value for this, but these are the three main ones, perhaps.)
    let a = {x: 1, y: 3}
    function f(c, s) {this.x = this.x * c + s;}
    f.apply(a, [3, 5]);
    a;                           // { x: 8, y: 3 }, 4, 1);
    a;                           // { x: 33, y: 3 }
    f.bind(a)(3, 8);
    a;                           // { x: 107, y: 3 }
  3. If called within a non-arrow function f that is a property of an object, and called in the expression obj.f(), it refers to obj, and the function is called a method.
    let x = {a: 1, b: function (x) {return x + this.a;}};
    x.b(2);                                    // 3
    // Wait we should use a more modern syntax
    let x = {a: 1, b(x) {return x + this.a;}};
    x.b(2);                                    // 3
    // The expression is evaluated dynamically, not statically
    let f = function (x) {return x + this.a;}
    let x = {a: 10, b: f};
    x.b(2);                                    // 12.
    // Hey let's bundle up methods with our data!
    let p = {
      x: 0,
      y: 0,
      move(dx, dy) {this.x += dx; this.y += dy;},
      reflect() {this.x = -this.x; this.y = -this.y;}
    p.move(5, 4);
    [p.x, p.y];      // [-5, -4]
  4. If used in a function invoked with the new operator, it refers to the object being created. Let’s get to this now.


The previous example made a point object containing data fields and methods. If we want to make millions of point objects, each one of them would have copies of the move and reflect functions. If you care about saving memory, we should put those functions in a prototype. Interestingly, Eich, way back in 1995, created an operator, called new, that facilitates a pattern of creating objects with a shared prototype. Here’s how it works:

function Point(x = 0, y = 0) {
  this.x = x;
  this.y = y;
Point.prototype.move = function (dx, dy) {this.x += dx; this.y += dy;}
Point.prototype.reflect = function () {this.x = -this.x; this.y = -this.y;}
Point.prototype.toString = function () {return `(${this.x},${this.y})`;}

let p = new Point(3, 7);  // THE new IS CRUCIAL!

When you call the function with new, the function you call behaves as a constructor which means:

This works because of something interesting: every function you create has two properties: length, which holds the number of parameters for the function, and prototype, which is an object with a constructor property, whose value is the function itself.


Exercise: We know that the prototype chain is searched when we try to read a property from an object that doesn’t have the property. But what happens if you try to write a property that doesn’t exist in an object, but does exist in an object higher in the prototype chain?

Class Syntax

There is a keyword class which you can use to build exactly the same structure we built above.

class Point() {
  constructor(x = 0, y = 0) {
    this.x = x;
    this.y = y;
  move(dx, dy) {this.x += dx; this.y += dy;}
  reflect() {this.x = -this.x; this.y = -this.y;}
  toString() {return `(${this.x},${this.y})`;}

let p = new Point(3, 7);  // THE new IS CRUCIAL!

This code creates a function called Point whose body is the constructor, and it assigns those three functions to Point.prototype. Please keep in mind that using the class keyword is nothing more than syntactic sugar for functions and prototypes. There are no such thing as classes in JavaScript. Only functions.

Exercise: Try out this code. Evaluate typeof Point. You got "function", right?

Prototype Chains

The class syntax has a little feature to automatically make prototype chains. Here’s an example:

class Person {
  constructor (name, birthday) { = name || "Unknown"
      this.birthday = birthday;
  age() {return new Date().getTime() - this.birthday.getTime();}

class Employee extends Person {
  constructor(name, birthday, id) {
    super(name, birthday); = id;

class Student extends Person {
  constructor(name, birthday, gpa) {
    super(name, birthday);
    this.gpa = gpa;

class Administrator extends Person {
  constructor(name, birthday, id) {
    super(name, birthday, id);

class Instructor extends Employee {
  constructor(name, birthday, id, department) {
    super(name, birthday, id);
    this.department = department;
Exercise: Draw a picture of this object family.
These so-called “deep class hierarchies” are frowned upon by some folks in the JavaScript community. But go ahead and use them if you know what you are doing and it makes sense for your application.

Crockford doesn’t use this, new, or prototypes

Douglas Crockford suggests that you do things like this:


TODO: Explain it

Regular Expressions

JavaScript has special syntactic sugar for regular expressions, for example


JavaScript’s regular expression language is pretty standard:

Two ways to create:

re = /a+bc/;
re = new RegExp("a+bc");

JavaScript doesn’t have as rich a regex language as most other languages, but it has enough for most cases. The complete reference is here. In practice, you will want to grab a third-party module like xregexp.


If there’s a match, returns an array of match info. If no match, returns null.
Simply returns true if there’s a match and false otherwise.
Without the g modifier, same as regex.exec(str). With the g modifier, returns an array of all matches.
Returns the index of the beginning of the match, or -1 if no match.
str.replace(regex, newTextOrFunction)
Replaces the matched part of the string with new text.
Returns an array of substrings split by the regex separator.



Accessing prototypes:

let basicCircle = {x:0, y:0, r:1}
let c = Object.create(basicCircle)
c.x = 2
c.color = 'blue'
Object.getPrototypeOf(c)                    // { x: 0, y: 0, r: 1 }
Object.getPrototypeOf(basicCircle)          // {}
Object.prototype.isPrototypeOf(basicCircle) // true
basicCircle.isPrototypeOf(c)                // true

Getting the properties of an object:

Object.keys(c)                             // [ 'x', 'color' ]
Object.getOwnPropertyNames(c)              // [ 'x', 'color' ]
let a = []; for (let p in c) a.push(p); a  // [ 'x', 'color', 'y', 'r' ]
c.hasOwnProperty('color')                  // true
c.hasOwnProperty('y')                      // false

Introducing Property Descriptors:

Object.getOwnPropertyDescriptor(c, 'x')
    // { value: 2,
    //   writable: true,
    //   enumerable: true,
    //   configurable: true }
c.x = 10
c.x                                                  // 10
Object.defineProperty(c, 'x', {writable: false})
Object.getOwnPropertyDescriptor(c, 'x')
    // { value: 10,
    //   writable: false,
    //   enumerable: true,
    //   configurable: true }
c.x = 500                                            // no error, but ...
c.x                                                  // 10

The attributes depend on how the object is created

a = {x: 1, y: 2}
Object.getOwnPropertyDescriptor(a, 'x')
    // { value: 1,
    //   writable: true,
    //   enumerable: true,
    //   configurable: true }
b = Object.create(Object.prototype, {x: {value: 1}, y: {value: 2}})
Object.keys(b)                            // []
Object.getOwnPropertyNames(b)             // [ 'x', 'y' ]
Object.getOwnPropertyDescriptor(b, 'x')
    // { value: 1,
    //   writable: false,
    //   enumerable: false,
    //   configurable: false }

What kind of attributes can we attach to properties?

A property can have EITHER a data descriptor OR an access descriptor.

What do these mean?

See the MDN page for defineProperty for great examples.

Preventing extensions, sealing, freezing

How can I get a handle on all of the objects in my system?

You can get the native objects, at least, as long as you can get a handle on the global object. Global variables, remember, are properties of the global object, and you know how to get properties of an arbitrary object.


A program is a sequence of statements and function declarations. Function declarations begin with function, function*, async function, async function*, or class. The statements are:


Keywords may not be used as identifiers:

await break case catch class const continue debugger default delete do else export extends finally for function if import in instanceof new return super switch this throw try typeof var void while with yield

Future Keywords may be used in the future as keywords:


The following are essentially reserved due to static semantic restrictions in some contexts:

let static implements package protected interface private public


From highest to lowest precedence:

Operators Associativity Description
without arguments
L member (rhs cannot start with a digit)
create instance
with arguments
N/A call
create instance
N/A postfix increment
postfix decrement
R logical not
bitwise not
unary negation
unary plus
prefix increment
prefix decrement
type name
evaluate and return undefined
** L exponentiation
L multiply
L add
L left shift
arithmetic right shift (sign fill)
logical right shift (zero fill)
L less than
less than or equal
greater than
greater than or equal
has property
has type
L similar to
not ==
equals (and same type)
not ===
& L bitwise and
^ L bitwise xor
| L bitwise or
&& L short-circuit logical and
|| L short-circuit logical or
?: R conditional
+= -=
*= /= %=
<<= >>= >>>=
&= ^= |=
R assignment
N/A return from generator
delegate to another generator
... N/A spread
, L comma

Good to know:

Built-in Objects

JavaScript, the language, tracks the ECMAScript Scripting Language Specification, so all of the standard objects in the ECMAScript specification are available to your JavaScript programs. Here are those objects, with a representative set of their properties, as of ES7 (The 7th edition of the ECMAScript Specification, a.k.a. ES2016):

The global
Infinity NaN undefined eval() isFinite() isNaN() parseFloat() parseInt() decodeURI() decodeURIComponent() encodeURI() encodeURIComponent() Math JSON Reflect Object() Function() Boolean() Number() String() Symbol() Array() Float32Array() Float64Array() Int8Array() Int16Array() Int32Array() Uint8Array() Uint8ClampedArray() Uint16Array() Uint32Array() ArrayBuffer() DataView() Date() RegExp() Set() WeakSet() Map() WeakMap() Proxy() Promise() Error() SyntaxError() RangeError() TypeError() ReferenceError() URIError() EvalError()
prototype create() assign() is() getPrototypeOf() setPrototypeOf() defineProperties() defineProperty() getOwnPropertyDescriptor() getOwnPropertyNames() getOwnPropertySymbols() keys() preventExtensions() isExtensible() seal() isSealed() freeze() isFrozen()
Object.prototypenullconstructor toString() toLocaleString() valueOf() hasOwnProperty() isPrototypeOf() propertyIsEnumerable()
E LN10 LN2 LOG2E LOG10E PI SQRT1_2 SQRT2 abs() acos() acosh() asin() asinh() atan() atanh() atan2() cbrt() ceil() clz32() cos() cosh() exp() expm1() floor() fround() hypot() imul() log() log1p() log10() log2() max() min() pow() random() round() sign() sin() sinh() sqrt() tan() tanh() trunc()
parse() stringify()
getPrototypeOf() setPrototypeOf() construct() ownKeys() has() defineProperty() getOwnPropertyDescriptor() get() set() apply() deleteProperty() isExtensible() preventExtensions()
length prototype
constructor toString() apply() call() bind()
Function instancesFunction.
name length prototype
constructor thisBooleanValue() toString() valueOf()
constructor toString() toLocaleString() valueOf() toFixed() toExponential() toPrecision()
prototype fromCharCode() fromCodePoint() raw()
constructor charAt() charCodeAt() codePointAt() startsWith() endsWith() includes() indexOf() lastIndexOf() slice() substring() toLowerCase() toUpperCase() toLocaleLowerCase() toLocaleUpperCase() normalize() localeCompare() trim() concat() repeat() match() search() replace() split() toString() valueOf()
String instancesString.
prototype for() keyFor() hasInstance() isConcatSpreadable iterator() match() replace() search() species() split() toPrimitive() toStringTag unscopables
constructor toString() valueOf()
constructor flags global ignoreCase unicode multiline sticky source test() exec() toString()
RegExp instancesRegExp.
prototype parse UTC now
constructor getDate() getTime() getFullYear() getMonth() getDay() getHours() getMinutes() getSeconds() getMilliseconds() getTimezoneOffset() getUTCDate() getUTCFullYear() getUTCMonth() getUTCDay() getUTCHours() getUTCMinutes() getUTCSeconds() getUTCMilliseconds() setDate() setTime() setFullYear() setMonth() setHours() setMinutes() setSeconds() setMilliseconds() setUTCDate() setUTCFullYear() setUTCMonth() setUTCHours() setUTCMinutes() setUTCSeconds() setUTCMilliseconds() toString() toISOString() toUTCString() toDateString() toTimeString() toLocaleString() toLocaleDateString() toLocaleTimeString() toJSON() valueOf()
prototype isArray() of() from()
constructor keys() values() entries() includes() find() findIndex() indexOf() lastIndexOf() slice() every() some() forEach() map() filter() reduce() reduceRight() pop() push() shift() unshift() copyWithin() join() concat() fill() sort() reverse() splice() toLocaleString() toString()
Array instancesArray.
prototype BYTES_PER_ELEMENT of() from()
constructor BYTES_PER_ELEMENT buffer byteLength byteOffset length keys() values() entries() includes() find() findIndex() indexOf() lastIndexOf() slice() every() some() forEach() map() filter() reduce() reduceRight() copyWithin() join() fill() sort() reverse() set() subarray() toLocaleString() toString()
constructor size has() keys() values() entries() add() clear() delete() forEach()
prototype isView
constructor byteLength slice()
constructor buffer byteLength byteOffset getInt8() setInt8() getInt16() setInt16() getInt32() setInt32() getUint8() setUint8() getUint16() setUint16() getUint32() setUint32() setFloat64() setFloat32() getFloat64() getFloat32()
constructor has() add() has() delete()
constructor size has() get() set() keys() values() entries() clear() delete() forEach()
constructor has() get() set() delete()
prototype all() race() resolve() reject()
constructor then() catch()
constructor name message toString()
constructor name message

Other Objects

Host environments provide lots of their own objects. You’re likely to see these in most web environments:

Anchor        Applet   Area         Arguments   Button     Checkbox   Crypto
Document      Event    FileUpload   Form        Frame      Hidden     History
HTMLElement   Image    Input        Layer       Link       Location   MimeType
Navigator     Option   Password     Plugin      Radio      Reset      Screen
Select        Style    Submit       Text        TextArea   Window

On the web, all of the elements (including images and video), attributes, and other pieces of the a web page are part of the Document Object Model or DOM. These are all visible to JavaScript, so most JavaScript programs essentially do graphics by manipulating the DOM (as in the Temperature Conversion script at the beginning of these notes). Unfortunately there are quite a few differences between browsers when it comes to the DOM.

There are two other ways to do graphics in JavaScript:

Most browsers have an additional object called XMLHttpRequest. This allows communication with a webserver without a page refresh, a programming style now called Ajax.

Server side environments provide a number of global objects, too. Here are some global objects in Node (beyond those defined by the ECMAScript specification):

console    setTimeout       Buffer         escape
process    clearTimeout     ArrayBuffer    unescape
module     setInterval      DataView
require    clearInterval    Intl
global     setImmediate
root       clearImmediate

JavaScript Libraries

Most serious JavaScript is done with third-party libraries that are not only full of functionality, like special effects (fading, animation, etc.) but that wonderfully hide all the cross-browser differences from the programmer. Then there are the frameworks, gazillions of them.

Probably the major JavaScript libraries and frameworks are:

You might like A Commentary on Google Closure Library.

On the server side, there are thousands and thousands of packages you can use in your code. Run

$ npm search

Versions of JavaScript

What people call the different “versions” of JavaScript vary a little bit, but it’s a good bet people agree on these versions:

Check Kangax's Compatibility Tables to see which implementations support which features of the different versions.

Interested in some history?

By the way, JavaScript is not like the other language with a similar name.


JavaScript is awesome, but sometimes you just gotta have fun. Watch Gary Bernhardt’s famous Wat talk.