Skip to content

Javascript concepts

sjagoori edited this page Jun 24, 2020 · 4 revisions

Table of contents

Closure

The concept

The concept of closures allows code to be declared in a function and be readable in a child-function (see hoisting). The child function, for example, read the declared variables from the parent function- or even the global variables whereas parent functions are unable to read variables declared in child functions; it works only outwards.

Code example

function init() {
  let name = 'Mozilla'; // name is a local variable created by init
  function displayName() { // displayName() is the inner function, a closure
    console.log(name); // use variable declared in the parent function
    let aaa ="aaa"
  }
  displayName();
  console.log(aaa) // cant see in child parent
}
init();

Source

Closures. (2020, May 31). MDN Web Docs. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

Context

In programming, the context is nearly always the scope within the code is written in. This means that, for example, this can refer to a variable within a function scope.

Strict mode vs. sloppy mode

Javascript exists in two modes; the sloppy mode (default) and the strict mode. In the strict mode, the compiler would instead of ignoring throw errors. This extends to non-writable global names and property.

* strict mode

'use strict'
undefinedVariable = 20

console.log(undefinedVariable)
// ReferenceError: undefinedVariable is not defined
* sloppy mode
undefinedVariable = 20

console.log(undefinedVariable)
// 20

Global context

The global context is the context that is not inside any function. In this context (if executed in a browser), this refers to the window which contains the properties of that window such as events and other metadata.

this.a = 20 

function something(){
  return this.a
}

console.log(something())
// undefined
console.log(this.a)
// 20

Function context

In the context of a function, it depends on how the function is called. In a scenario where the code is executed in sloppy mode, the value of this would be window whereas in a strict mode, it'd be undefined.

function strictMode() {
  'use strict'
  return this
}

function sloppyMode() { 
  return this
}

console.log(typeof strictMode()) 
// undefined
console.log(typeof sloppyMode()) 
// object- where all window properties are

Class context

In the context of classes, this can refer to multiple things. For example, in the constructor, the this refers to the incoming value whereas in getType() this refers to the type() function in the class.

class Pokemon {
  constructor() {
    this.getType.bind(this);
  }

  getType() {
    console.log(`This is a ${this.type} type pokemon`);
  }
  get type() {
    return 'fire';
  }
}

const charmander = new Pokemon();
charmander.getType();
// This is a fire type pokemon

Source

this. (2020, June 2). Retrieved from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

Hoisting

Hoisting is the process of the VM putting the bindings in the memory before executing the rest of the code.

For example, if you declare a function, it'll be put in the memory before it can be called in the code. This process is invisible to the user.

catName("Chloe");
// My cat's name is Chloe

function catName(name) {
  console.log("My cat's name is " + name);
}

catName("Tiger");
// My cat's name is Tiger

So, calling a function that is defined later in the code will work because of hoisting.

Variable leaking

In some cases, variables that are improperly declared get still hoisted; a variable "declaration" will get a reserved position in the memory due to hoisting even though it has not been declared yet.

function someName(){ 
 leakMe = "Since I'm not declared, I'm global"
}

console.log(leakMe)
// something


function anotherName(){
 var dontLeakMe = "Since I've been declared properly, I'm not leaking and available outside my scope"
}

console.log(anotherName)
// Uncaught referenceError: anotherName is not defined *angry computer noises*

Sidenote

Only variables that are declared will be put into a reserved place in the memory.

console.log(num); // Returns undefined, as only declaration was hoisted, no initialization has happened at this stage 
var num; // declaration
num = 6; // initialization
* no declaration has taken place here

console.log(num); // throws ReferenceError exception 
num = 6; // initialization

Source

Scope

Scopes are metaphorical fences for code; they cant reach over the fence. These fences are the scopes wherein declared variables live in. For the code inside the fences, it is possible to see the code on the outside, but code from the outside cannot look on the other side of the fences.

For example, declared variables in functions are behind a fence (inside if you will). That means that another piece of code that is not between de fencing cannot retrieve its values; it's outside its scope.

let someFunction = () => {
  let value = "Can you read me?"
  console.log(value)
  // Can you read me?
}

console.log(value)
// value is not defined

Another example, variables that are declared inside loops and conditions (which are functions btw) follow the exact same principle; they are not accessible from outside their scope.

if (1 === 1){
  let value = "equal"
  console.log(value)
  // equal
}

console.log(value)
// value is not defined

Variables that are not declared within any scope are global, that means every piece of code can read and use it.

let value = "global value" 

function someFunction(){
  console.log(value)
  // global value
}

console.log(value)
// global value

Const, let, and vars

In ES6 bindings have their own scopes, some declarations have a broader scope than the other or cannot be changed.

Let's

A let binding can be updated with another/new declaration; in the second time declaring it, it isn't required to declare it is a let.

let begging = "hopelijk is dit voldoende"
begging = "oops, didn't mean to say that"

console.log(begging)
// oops, didn't mean to say that 
let inGlobalScope = "I'm the global one."

if (5 > 10) {
  let inGlobalScope = "I'm no longer in the global scope"
  console.log(inGlobalScope)
  // I'm no longer in the global scope
}

console.log(inGlobalScope)
// I'm the global one.

Var

The var declaration is globally available (if declared so). A redeclaration requires a var again, and the original value will get updated. This is especially convenient to have in loops.

var inGlobalScope = "I'm the original"

if (5 > 10) {
  var inGlobalScope = "I'm no longer the original"
  console.log(inGlobalScope)
  // I'm no longer the original
}

console.log(inGlobalScope)
// I'm no longer the original

Const

Const is a constant binding; these cannot be redeclared later on unless the data type allows it.

const username = "sjagoori"

username = "nolongersjagoori"
// Uncaught TypeError: Assignment to constant variable.

const mutableConstBinding = []
mutableConstBinding.username = "sjagoori"

console.log(mutableConstBinding.username)
// sjagoori

Source

Progressive Enhancement

Progressive enhancement is a methodology for developing web applications. Using this method, you will be able to serve your website to anyone on accessibility spectrum.

Progressive Enhancement is a strategy for web design that emphasizes core web page content first. This strategy then progressively adds more nuanced and technically rigorous layers of presentation and features on top of the content as the end-users browser/Internet connection allows. — Wikipedia

The strategy

To serve the visitors that might not have the most stable, consistent, or newest device, it's essential to build your website in a way that it will still serve its purpose. To achieve that, it's necessary to serve the core page content first. The main goal is to make the basic function and content accessible to everyone. So, your website should be accessible without the framework or javascript working. The core content of the website should not depend on them.

The core principles are:

  • Basic content should be accessible to all web browsers
  • Basic functionality should be accessible to all web browsers
  • Sparse, semantic markup contains all content
  • Enhanced layout is provided by externally linked CSS
  • Enhanced behavior is provided by unobtrusive, externally linked JavaScript
  • End-user, web browser preferences, are respected

Progressive enhancement consists of 3 layers: the functional, the usable, and the pleasurable layer. Its first layer, the functional layer, focusses on the semantic usage and structure of HTML. It's important to get this part right if you want to build features on top and around it. Having a solid base takes away complications later on in the development process.

The second layer, the usable layer, focusses on the usability of a page. The page is functional but is not user-friendly yet. Styling can be used to make the UI more attractive and the UX better. Some examples are the usage of colors, or different states such as the hover, active, and focus state.

The third and last layer is the pleasurable layer; this layer focusses on the pleasurable part of the website, such as animations. This layer consists of additions to the functional features from the first layer.

Sources

Progressive Disclosure

Progressive disclosure is a strategy for managing information complexity. When you use progressive disclosure, you show only the information necessary at that point in the interaction. And you display more advanced functionalities of the app interface as the user interacts with it.

The concept of progressive disclosure is essential to inform users of what the result of their interaction will be. For example, when a user uses a filter to filter out the search result, the system can display how many products will be shown if the user enters those filters. Another example is when a button tells where it will lead you. The user will know what to expect before clicking it.

Progressive disclosure helps the user in feature-rich websites by disclosing what an element does or what to expect.

Sources