JS Scoping, Hoisting and var/let/const

JavaScript (similar to PHP) is a dynamically types scripting language which means, that variables don’t have a fixed variable type.

myvar = 1;
myvar = “Ich bin ein Text”;
myvar = ["Chevrolet", "Ford", "Audi"];

In statically typed languages like Java you can e.g. assign an internger value to a string variable.

Scope

Local Variables

// code here can NOT use carName

function myFunction() {
  var carName = "Ford";
  // code here CAN use carName
}

Global Variables

var carName = "Volvo";

// code here can use carName

function myFunction() {
  // code here can also use carName
}

Hoisting

Hoisting is the “automatic movement of variable definitions to the beginning of the current scope”.

That means the following 2 scripts produce the same result:

x = 5; // Assign 5 to x

elem = document.getElementById("demo"); // Find an element
elem.innerHTML = x;                     // Display x in the element

var x; // Declare x
var x; // Declare x
x = 5; // Assign 5 to x

elem = document.getElementById("demo"); // Find an element
elem.innerHTML = x;                     // Display x in the element

This ONLY happens with variables defined with “var”!
“let” and “const” don’t have this Hoisting behaviour.

Here one more important difference! Hoisting occurs ONLY on the variable definition, not the initialisation with a value.

That means the following 2 scripts produce a different result:

var x = 5; // Initialize x
var y = 7; // Initialize y

elem = document.getElementById("demo"); // Find an element
elem.innerHTML = x + " " + y;           // Display x and y
var x = 5; // Initialize x

elem = document.getElementById("demo"); // Find an element
elem.innerHTML = x + " " + y;           // Display x and y

var y = 7; // Initialize y

In the 2 script we don’t get an error due to the fact, that the variable definition is being hoisted to the top, but the value assignment with 7 only happens at the end.

Therefore the 2 script from above is the same as this:

var x = 5; // Initialize x
var y;     // Declare y

elem = document.getElementById("demo"); // Find an element
elem.innerHTML = x + " " + y;           // Display x and y

y = 7;    // Assign 7 to y

var vs let & const

With ES6 (ECMAScript 2015) 2 new possibilities how to declare variables have been added.:

let is a mutable variable, const is an immutable variable.

That means a variable defined with let can have different values all the time but a variable defined with const can only have 1 value.

If you try to change an already set const variable you will get an error.

But the main difference between var to let & const is that these 2 are only available in their respective scopes and not “globally”.

Here are some examples with the “old” var system and the “new” let/const system.

var x = 10;
// Here x is 10
{
  var x = 2;
  // Here x is 2
}
// Here x is 2
var x = 10;
// Here x is 10
{
  let x = 2;
  // Here x is 2
}
// Here x is 10

If you define a “global” let variable you will be able to read its value inside functions that are placed on the same scope or inside the corrent scope.

let x = 10;

function myFunc(){
  console.log(x);
}

myFunc();

// Outputs 10

But you are not allowed to “redeclare” x in the myFunc function like:

let x = 10;

function myFunc(){
  console.log(x);
  let x = 2;
  console.log(x);
}

myFunc();
console.log(x);

VM611:4 Uncaught ReferenceError: Cannot access 'x' before initialization
    at myFunc (<anonymous>:4:15)
    at <anonymous>:9:1

You are only allowed to assign new values to it like:

let x = 10;

function myFunc(){
  console.log(x);
  x = 2;
  console.log(x);
}

myFunc();
console.log(x);

// Outputs
10
2
2

This means the scope of a variable is determined when the decleration of the variable is being done and not when or in which scope it is used.

Sources:
https://www.w3schools.com/js/js_scope.asp
https://www.w3schools.com/js/js_hoisting.asp

AMD, CJS, UMD, ESM – Modular JavaScript

As a remindet: JavaScript can be used for the frontend (browser) as well as the backend (serverside via Node.js). The following methods do apply to either one of them or sometimes both.

Asynchronous Module Definition (AMD)

AMD is a way to load JS asynchronously usually used in frontend applications.

define(['dep1', 'dep2'], function (dep1, dep2) {
    //Define the module value by returning a value.
    return function () {};
});

The main implementation of the AMD functionality is done by RequireJS.

Therefore to use AMD to load more JS Modules you frst have to load RequireJS. See HERE

CommonJS (CJS)

CJS loads JS modules synchronously not like AMD.

//importing 
const doSomething = require('./doSomething.js'); 

//exporting
module.exports = function doSomething(n) {
  // do something
}

CJS is primarily used in Node.js and therefore for serverside JavaScript. The modules are loaded via the command “require” and module definitions are done via “module.exports“.

CJS does NOT work in the browser.

Universal Module Definition (UMD)

After some time bot AMD as well as CJS generally used but they are not compatible with each other.

Therefore UMD was developed so JS can be written which is compatible with both AMD and CJS worlds.

(function (root, factory) {
    if (typeof define === "function" && define.amd) {
        define(["jquery", "underscore"], factory);
    } else if (typeof exports === "object") {
        module.exports = factory(require("jquery"), require("underscore"));
    } else {
        root.Requester = factory(root.$, root._);
    }
}(this, function ($, _) {
    // this is where I defined my module implementation

    var Requester = { // ... };

    return Requester;
}));

But till now UMD is just used as a fallback if either AMD or CJS is not availalbe for your desired JS module. Why? See next chapter.

ES Modules (ESM – recommended variant)

ES modules are the “official” way how to write modular JS defined by the ES6 standard.

// in index.html
<script type="module" src="main.js"></script>

// in main.js
import {addTextToBody} from './util.js';
addTextToBody('Modules are pretty cool.');

// in util.js
export function addTextToBody(text) {
  const div = document.createElement('div');
  div.textContent = text;
  document.body.appendChild(div);
}

So its like the functionality of AMD (asynchron loading) notation of CJS.

Here an example where a module is “directly” loaded as well as an “asynchron” module after 5 seconds.

// index.html
<html>
    <head>
        <script type="module" src="main.js"></script>
    </head>
    <body></body>
</html>

// main.js
import {addTextToBody} from './util.js';
addTextToBody('Modules are pretty cool.');

setTimeout(function(){
    import('./later.js')
    .then(module => {
      module.laterFuncton();
    })
}, 5000);

// util.js
export function addTextToBody(text) {
    const div = document.createElement('div');
    div.textContent = text;
    document.body.appendChild(div);
}

// later.js
export function laterFuncton() {
    alert("hello");
}

Browser-Support: https://caniuse.com/#feat=es6-module

Source: https://dev.to/iggredible/what-the-heck-are-cjs-amd-umd-and-esm-ikm

What is JavaScript?

JavaScript (JS) is a Scripting language which is used for interactive browser elements as well as server logic.

Versions of JavaScript

The official name of JavaScript is “ECMAScript”.

Since 2015 the versioning system has changed from adding just 1, 2, 3 to ECMAScript and instead add the year of release.

This means ES6 = ECMAScript 2015 | ES7 = ECMAScript 2016 etc.

VerOfficial NameDescription
1ECMAScript 1 (1997)First Edition.
2ECMAScript 2 (1998)Editorial changes only.
3ECMAScript 3 (1999)Added Regular Expressions.
Added try/catch.
4ECMAScript 4Never released.
5ECMAScript 5 (2009)Added “strict mode”.
Added JSON support.
Added String.trim().
Added Array.isArray().
Added Array Iteration Methods.
5.1ECMAScript 5.1 (2011)Editorial changes.
6ECMAScript 2015Added let and const.
Added default parameter values.
Added Array.find().
Added Array.findIndex().
7ECMAScript 2016Added exponential operator (**).
Added Array.prototype.includes.
8ECMAScript 2017Added string padding.
Added new Object properties.
Added Async functions.
Added Shared Memory.
9ECMAScript 2018Added rest / spread properties.
Added Asynchronous iteration.
Added Promise.finally().
Additions to RegExp.
10ECMAScript 2019Added Array.flat().
Added Object.fromEntries().
Added String.trimStart() & trimEnd().
Added Symbol.description.
11ECMAScript 2020Added BigInt Typ.
Added globalThis.
Added Nullish Coalescing Operator (??).
Added Optional Chaining Operator (?.).

These versions are “just” the description of how the programming language should behave. The implementation of these behaviours are delivered by JavaScript Engines like:

  • V8 is the most common JS Engine used by:
    • Chrome/Chromium
    • Node.js and Deno
    • Edge
  • SpiderMonkey used by Firefox
  • Nitro used by Safari
  • Chakra used by Internet-Explorer

Browser Support (ES6)

BrowserVersionDate
Chrome51Mai 2016
Firefox54Juni 2017
Edge14Aug 2016
Safari10Sep 2016
Opera38 Juni 2016

Internet-Explorer is the only browser wich does not support ES6.

Clientside JS (Browser)

Clientside JS is being executed on each device which e.g. has your website open.

In Browsers JS is used to for example adjust the DOM without reloading the page.

document.addEventListener("DOMContentLoaded", function() {
  function createParagraph() {
    let para = document.createElement('p');
    para.textContent = 'You clicked the button!';
    document.body.appendChild(para);
  }

  const buttons = document.querySelectorAll('button');

  for(let i = 0; i < buttons.length ; i++) {
    buttons[i].addEventListener('click', createParagraph);
  }
});

Via the JS Object “document” you can check, adjust and add elements shown in your website.

But there also some other APIs available as well, such as:

  • Geo Location (navigator.geolocation) to get the current location of the user
  • WebGL and Canvas API to create complex animations or 3D elements
  • Audio & Video API

Serverside JS (Node.js)

Serverside JS is executed on the server to e.g. send text back to a client.

There are many frameworks which make it easier to create modern JS based websites and/or backends.

For more information on Node.js see HERE.

Source:
https://www.w3schools.com/js/js_versions.asp
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/What_is_JavaScript