JavaScript (aka ECMAScript aka ES)

Versions, Revisions

  • ES6 = ECMAScript 6 = ECMAScript 2015
    • arrow functions

Crash Course

see YouTube (Code)

Terminology

  • JavaScript runtime refers to where your javascript code is executed when you run it. That said, javascript can be executed on google chrome, in which case your javascript runtime is v8, if on mozilla - it is spidermonkey, if IE - then its chakra and if on node, again its v8. (stackoverflow comment under answer)
  • I/O: In practice, the web browser or other runtime system provides JavaScript APIs for I/O.

Implementations

  • Google V8
    • see this discussion on stackoverflow
    • see Terminology → “JavaScript runtime”
    • from Wikipedia:
      • developed by the Chromium Project for Google Chrome and Chromium web browsers
      • V8 compiles ECMAScript directly to native machine code using just-in-time compilation before executing it
        • JIT compilation aka dynamic compilation ( source )
          • a method for improving the performance of interpreted programs
          • During execution the program may be compiled into native code to improve its performance.
          • Advantages:
            • Dynamic compilation has some advantages over static compilation.
            • When running Java or C# applications, the runtime environment can profile the application while it is being run.
            • This allows for more optimized code to be generated.
            • If the behavior of the application changes while it is running, the runtime environment can recompile the code.
      • The compiled code is additionally optimized (and re-optimized) dynamically at runtime, based on heuristics of the code’s execution profile.
      • Optimization techniques used include
        • inlining
        • elision of expensive runtime properties
        • inline caching.
      • used in
        • Chromium-based web browsers
        • Firefox - parts of V8 ported to the browser for regular expressions parsing
        • many more apps (see Wikipedia)

Repl (JavaScript on the Command Line)

Useful: Use <tab><tab> to autocomplete commands.

$ node
Welcome to Node.js v19.6.0.
Type ".help" for more information.
> 

Formatting, Syntax Highlighting

  • Install javascript syntax highlighting using nvim-treesitter.
  • Install javascript formatting using coc-prettier.

CDNs

CDN: A content delivery network, or content distribution network.

Common CDNs

List

Press ctrl + shift + E and roload the page in Firefox to see the used CDNs (in column “Domain”).

CDNs (by popularity):

  • Google Hosted Libraries
  • cdnjs
    • e.g. cdnjs.cloudflare.com
  • jsDelivr
    • e.g. cdn.jsdelivr.net
    • official CDN of Bootstrap

Syntax

Types

Strings

UTF-8

From Wikipedia:

  • the dominant encoding for the World Wide Web (and internet technologies)
  • accounting for 97.9% of all web pages

UTF-16

From Wikipedia:

  • for security reasons browser applications should not use UTF-16
  • UTF-16 is used by systems such as
    • the Microsoft Windows API,
    • the Java programming language and
    • JavaScript/ECMAScript.

Print

JavaScript can “display” data in different ways: w3schools

  • Writing into an HTML element, using innerHTML.
  • Writing into the HTML output using document.write().
  • Writing into an alert box, using window.alert().
  • Writing into the browser console, using console.log().

.constructor property and .constructor.name stackoverflow

  • Check this bindings, etc

Variables

let

  • only use this, if you know the variable will change, otherwise use const
    • makes the code more robust

const

mdn

  • creates block-scoped constants
  • The value of a constant
    • can’t be changed through reassignment (i.e. by using the assignment operator =), and
    • it can’t be redeclared (i.e. through a variable declaration).
  • However, if a constant is an object or array its properties or items can be updated or removed.

Types

Check types via typeof operator

typeof Math.LN2 === "number";
typeof declaredButUndefinedVariable === "undefined";
typeof undeclaredVariable === "undefined";
typeof { a: 1 } === "object";

For objects use the .constructor property and .constructor.name stackoverflow

Numbers

Number.prototype.toLocaleString

const currencyOptions = {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2,
}

total.toLocaleString(undefined, currencyOptions)
  • Convert total from a number to a string with two decimal places.
  • this will also convert the number to a string according to the numerical conventions that match the browser’s locale
  • Use undefined as the first argument to toLocaleString to use the system locale rather than specifying a locale

Arrays

Spread

digitalocean

I.e. ... notation, e.g.

const cart = [...state.cart];

Use cases:

  • instead of const concatArray = array1.concat(array2) use const concatArray = [...array1, ...array2]
    • both methods do not change the existing arrays, but instead return a new array
  • instead of const pushedArray = array1.push(array2[0]) (modifies array1) use const pushedArray = [...array1, array2] (does not modify array1)
  • shallow copying
    • i.e. creating a new array from the existing one and adding a new item to the end without changing the existing one

In JavaScript, when you create an object or array and assign it to another variable, you are not actually creating a new object - you are passing a reference.

  • Shallow Copy: spread allows to make a shallow copy of an array or object without changing the existing one
    • i.e. any top level properties will be cloned, but nested objects will still be passed by reference

Array.prototype.slice

stackoverflow

Get the last element:

var my_array = /* some array here */;
var last_element = my_array[my_array.length - 1];
  • Do not use my_array.slice(-1)[0], it is too slow.

Array.prototype.splice

mdn

return: An array containing the deleted elements.

The splice() method changes the contents of an array by removing or replacing existing elements and/or adding new elements in place (i.e. splice() modifies the original array).

  • To access part of an array without modifying it, see slice().
  • a mutating method: It may change the content of this.
  • Although strings are also array-like, this method is not suitable to be applied on them, as strings are immutable.
  • Negative index counts back from the end of the array.
some_array.splice(start)   # remove all elements after index "start"
some_array.splice(start, deleteCount)   # remove "deleteCount" elements after index "start" and keep the rest
some_array.splice(start, deleteCount, item1)
some_array.splice(start, deleteCount, item1, item2, itemN)

Array.prototype.reduce

mdn

The reduce() method executes a user-supplied “reducer” callback function on each element of the array, in order, passing in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is a single value.

Initial value: The first time that the callback is run there is no “return value of the previous calculation”. If supplied, an initial value may be used in its place. Otherwise the array element at index 0 is used as the initial value and iteration starts from the next element (index 1 instead of index 0).

Example:

const array1 = [1, 2, 3, 4];

// 0 + 1 + 2 + 3 + 4
const initialValue = 0;
const sumWithInitial = array1.reduce(
  (accumulator, currentValue) => accumulator + currentValue,
  initialValue
);

console.log(sumWithInitial);
// Expected output: 10

Array.prototype.indexOf

array1.indexOf(x)
  • index of the first instance of x in an array1
  • return -1 if x is not present

Lists

In JavaScript:

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);
console.log(doubled);

Functions

Define Functions

Ways to Define Functions:

  • function declaration mdn
  • function expressions mdn
  • method definition mdn
    • a shorter syntax for defining a function property in an object initializer. It can also be used in classes.
    • examples

Anonymous Functions

From javascripttutorial.net:

An anonymous function is a function without a name.

(function () {
   //...
});

An anonymous function is not accessible after its initial creation. Therefore, you often need to assign it to a variable:

let show = function () {
    console.log('Anonymous function');
};

show();

In this example, the anonymous function has no name between the function keyword and parentheses ().

In practice, you often pass anonymous functions as arguments to other functions. For example:

setTimeout(function() {
    console.log('Execute later after 1 second')
}, 1000);

Arrow Function Notation

ES6 introduced arrow function expressions that provide a shorthand for declaring anonymous functions.

From w3schools: If you have only one parameter (here: val), you can skip the parentheses as well:

hello = (val) => "Hello " + val;
// instead, you can use
hello = val => "Hello " + val;

Anonymous Functions as arguments

In practice, you often pass anonymous functions as arguments to other functions:

setTimeout(function() {
    console.log('Execute later after 1 second')
}, 1000);

this

Context

context: In JavaScript, context refers to an object. Within an object, the keyword this refers to that object (i.e. self), and provides an interface to the properties and methods that are members of that object. When a function is executed, the keyword this refers to the object that the function is executed in. source

In Arrow Functions

in an arrow function: You cannot rebind this in an arrow function. It will always be defined as the context in which it was defined. If you require this to be meaningful you should use a normal function. stackoverflow

w3schools (scroll down to section “What About this?”)

  • In regular functions the this keyword represented the object that called the function, which could be the window, the document, a button or whatever.
  • With arrow functions the this keyword always represents the object that defined the arrow function.

Try these examples!!!

  • example with normal function
    • shows that for a regular function this will always be the caller
  • example with arrow function
    • shows that for an arrow function it does not matter who is the caller, this will always be the “definer
  • also modify the example above and try running Example 1 and 2 below (modified from digitalocean):
    • Note:
      • in Example 1: document.write('\n') does not work in the code below: In HTML, all whitespace (including newlines) is collapsed and treated as a single space. stackoverflow
      • in Example 1: <br/> is the XHTML version of <br>. Since you’re not using XHTML, you would just use <br>. (How do I know you’re not using XHTML? Because you’re using document.write, which you can’t use in XHTML.) stackoverflow

Example 1: “this” in arrow functions

<script>
const whoAmI = {
  name: 'Leslie Knope',
  regularFunction: function() {
    document.write(this.name + '<br/>')
  },
  regularFunction2: function() {
    document.write(this.name + '<br/>')
  },
  arrowFunction: () => {
    document.write(this)
  },
}

whoAmI.regularFunction() // "Leslie Knope"
whoAmI.regularFunction2() // "Leslie Knope"
whoAmI.arrowFunction() // [object Window]
</script>

Example 2: event.currentTarget, “this” in arrow functions

<script>

const button = document.createElement('button')
button.textContent = 'Click me'
document.body.append(button)

class Display {
  constructor() {
    this.displayString = 'New text'

    // In an arrow function "this" always refers to the context (=object) in which the 
    // arrow function was defined, ie. here the "Display" class.
    const changeText = event => {
      event.target.textContent = this.displayString;
    }
 
    button.addEventListener('click', getText)
    button.addEventListener('click', changeText)
   
    // Here, "this" refers to the "event.currentTarget" object, ie. "button" which
    // is outside of the "Display" class.
    function getText(event) {
    	document.getElementById("demo").innerHTML += this.textContent
    }    
  }
}

new Display()

</script>

Sidenote about Example 2:

  • Why can we call getText() before it is defined?
  • Why can we not call changeText() before it is defined?
  • answer: see stackoverflow

Some Scenarios

source:

  • When a function executes in the global context, this refers to the global, or window object
  • When a function is a method of an Object, this refers to that object (unless it is manually executed in the context of a different object)
  • When a function executes inside of another function (no matter how deeply nested), this refers to the object whose context within which it is executed
  • When you instantiate a constructor function, inside of the instance object, this refers to the instance object

TypeScript (Microsoft)

  • a strict syntactical superset of JavaScript
  • adds optional static typing to the language
  • designed for the development of large applications
  • transpiles to JavaScript
  • As it is a superset of JavaScript, existing JavaScript programs are also valid TypeScript programs.
  • developed and maintained by Microsoft

Web APIs

mdn list of Web APIs

“Web APIs are typically used with JavaScript, although this doesn’t always have to be the case.”

“JavaScript has application programming interfaces (APIs) for working with text, dates, regular expressions, standard data structures, and the Document Object Model (DOM).” “JavaScript” Wikipedia

DOM

One Web API.

Interfaces

Element

Instance Properties
  • .innerHTML gets or sets the HTML or XML markup contained within the element. mdn

Event

Syntax

HTML Events

<button onclick="activateLasers()">
  Activate Lasers
</button>

JavaScript Events

  • either: object.onclick = function(){myScript};
  • or: object.addEventListener("click", myScript); ( see .addEventListener() )

React Events

  • React events are named using camelCase, rather than lowercase.
  • With JSX you pass a function as the event handler, rather than a string.
  • e.g. <button onClick={function}>
event Object

event

  • One can access the current event through window.event. Just using event is implicitly accessing window.event. stackoverflow
  • a global variable
event.target, event.currentTarget
  • .currentTarget: doc
    • “always refers to the element to which the event handler has been attached, as opposed to Event.target, which identifies the element on which the event occurred and which may be its descendant.”
  • .target: doc
    • “a reference to the object onto which the event was dispatched.”

“We’re using event.target to get the element that was the target of the event (that is, the innermost element). If we wanted to access the element that handled this event (in this case the container) we could use event.currentTarget.” mdn: note below this section

“Here you can see we are including an event object, e, in the function, and in the function setting a background color style on e.target — which is the button itself. The target property of the event object is always a reference to the element the event occurred upon. So, in this example, we are setting a random background color on the button, not the page.” mdn

  • “Note: You can use any name you like for the event object — you just need to choose a name that you can then use to reference it inside the event handler function. e/evt/event is most commonly used by developers because they are short and easy to remember. It’s always good to be consistent - with yourself, and with others if possible.”
onClick (Event)
  • in React notation: <button onClick={function}>
Event Handler
  • some_element.addEventListener() method
    • The addEventListener() method attaches an event handler to the specified element.
    • The addEventListener() method attaches an event handler to an element without overwriting existing event handlers.
    • You can add many event handlers to one element.
    • You can add many event handlers of the same type to one element, i.e two “click” events.
    • You can add event listeners to any DOM object not only HTML elements. i.e the window object.

Performance

Minification

Tools for Minification:

  • jsDelivr CDN can also minify any file in JavaScript, CSS, or SVG format, which can reduce loading times. (source)

Wikipedia:

“The process of removing all unnecessary characters from the source code of interpreted programming languages or markup languages without changing its functionality.”

“These unnecessary characters usually include white space characters, new line characters, comments, and sometimes block delimiters, which are used to add readability to the code but are not required for it to execute.”

“Minification reduces the size of the source code, making its transmission over a network (e.g. the Internet) more efficient.”