Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.


preamble

also remember that we focus on the browser runtime here
refer to this screenshot to spot the browser console


console.log() function

console.log(1, "two", [3, "four"])
1 two [ 3, "four" ]

see also below how to format strings with backticks a la Python f-strings


syntax

tests and loops


== vs ===

talking of tests, a common pitfall for newcomers is the difference between == and ===[2]

console.log( 10 == '10' )    // true - loose equality
console.log( 10 === '10' )   // false - strict equality
true
false

C-style for loop

for (let i=0; i<2; i++) {
    console.log(i)
}
0
1

switch

the switch statement in JavaScript is similar to the ones in C++ and Java
it will branch your control flow into a location that depends on the subject’s value

do not forget the break statements !

switch (a) {
    case 0:
        console.log("ZERO")
        break
    case 10:
        console.log("TEN")
        break
    case 20:
        console.log("TWENTY")
        break
    default:
        console.log("NONE")
}
NONE

variables

declaration

let n = 10
console.log(typeof(n))

// possible since declared with let
n += 20
number
30
const s = "hello world"
typeof(s)

// we could not do this
// because declared with const
// s += ' john'
"string"

Python-style unpacking

// there is a form of parallel assignment
// similar to what Python offers

let [py, thon] = [10, 20]

console.log(py, thon)
10 20

object unpacking

anticipating a bit, but there’s a very handy construction that looks a bit like the one above

// you receive some data from the outside
const data = {height: 100, width: 200, radius: 20, linewidth: 5}

// and you're interested in extracting width and height
// in two variables of the same name; easy !
const {height, width} = data

console.log(height, width)
100 200

variable scope


blocks {} and scope illustrated

the elementary unit for scope is the block - which is materialized by {}

let variable2 = "outermost"
{
    let variable2 = "intermediate"
    {
        let variable2 = "innermost"
        console.log("level 2", variable2)
    }
    console.log("level 1", variable2)
}
console.log("level 0", variable2)
level 2 innermost
level 1 intermediate
level 0 outermost

do not use var !


globals

context (browser components mostly) is exposed to programer through a set of global variables, e.g.


formatting with backticks

in JS, the backticks `` feature reminds of Python’s f-strings

let [x, y] = [100, 200]

// the `` is very similar to Python's f-strings
// except that you use ${expression} 
// note the extra $ as compared to Python

console.log(`x = ${x} and x+y = ${x+y}`)
x = 100 and x+y = 300

functions

like in other languages, and we have seen examples already

// the old way

function foo(x, y) {
    console.log(`${x} + ${y} = ${x+y}`)
}

foo(10, 20)
10 + 20 = 30
// a more fashionable way - similar to Python's lambdas

const bar = (x, y) => console.log(`from bar: ${x} + ${y} = ${x+y}`)
bar(100, 200)
from bar: 100 + 200 = 300
// you can use { } if the code is more than one-line
// but make sure to explicitly use 'return' if you do !
const bar2 = (x, y) => {
    let [x2, y2] = [x**2, y**2]
    return x2+y2;
}

bar2(10, 20)
500

loose parameter binding

function fuzzy(x, y, z) {
    console.log(`x = ${x}  y = ${y} z = ${z}`)
}
fuzzy(10)
fuzzy(10, 20)
fuzzy("abc", "def", "ghi")
// and even this !
fuzzy("abc", "def", "ghi", "trashed")
x = 10  y = undefined z = undefined
x = 10  y = 20 z = undefined
x = abc  y = def z = ghi
x = abc  y = def z = ghi

duck typing

like in Python, objects are typed, but variables are not bound to a given type

function foo(x, y) {
    console.log('x is a ', typeof(x))
    console.log(`${x} + ${y} = ${x+y}`)
}

// like in Python, function arguments are not statically typed
foo('abc', 'def')
x is a  string
abc + def = abcdef

this

// for example in this context, it's unclear what 'this' refers to
function show_this() {
    console.log(typeof(this))
}

show_this()
undefined

exceptions

JavaScript supports exceptions, just like Python, with the same bubbling mechanism
that scans the call stack until a catch statement is found

try {
    // referring to an unknown variable
    unknown
} catch (err) {
    console.log(`OOPS name=${err.name}, message=${err.message}`)
}
OOPS name=ReferenceError, message=unknown is not defined

classes

as of ES2015, the language has a proper class statement

class Vector {
    // just like Python's __init__
    // NO NEED to pass 'self' in JavaScript
    constructor(x, y) {
        this.x = x
        this.y = y
    }

    // same for a regular method
    display() {
        console.log(`[Vector x=${this.x} y=${this.y}]`)
    }
}

let vector = new Vector(10, 20)
vector.display()
[Vector x=10 y=20]

notes on classes

NOTICE the following facts from that first class example :


get / set (advanced)

// get / set example

class Temperature {
    constructor(temperature) {
        this.kelvin = temperature
        // "set kelvin(temperature)" will be called
    }

    get kelvin() {
        return this._kelvin
    }

    set kelvin(temperature) {
        if (temperature < 0) {
            console.log("negative - refusing to set")
            return
        }
        this._kelvin = temperature

        // we must use the hidden variable this._kelvin
        // that will store the value entered
        // and will be returned when we ask for this.kelvin
        // thanks to the get kevin() function

        // if we had written this.kelvin = temp_value
        // that would call set kelvin(temp_value) again
        // and we would have an infinite loop

    }
}
let temp = new Temperature(10)
temp.kelvin = -10
negative - refusing to set
-10
temp
Temperature { _kelvin: 10 }

Footnotes
  1. being a Pythonist at heart, I prefer omitting semicolons whenever possible; this is not a very widespread practice though if I’m being honest

  2. this resonates a bit, but not quite exactly, with Python that has == and is to compare values vs identities