JavaScript
Design Patterns

Prototyper

[[Prototype]]

Varje objekt har en prototyp:
en egenskap som innehåller gemensamma funktioner och variabler för alla objekt som du skapar.

Varje objekt ärver från Object

var a = {}
a --> Object --> null
Object.create()
var a = {};
var a = Object.create(Object.prototype);
var b = Object.create(null);

Om du vill ha ett helt tomt objekt

Ref: Object.create();
var a = {};
var b = Object.create(a)
b --> a --> Object --> null
var a = Object.create(null);
a --> null

Function.[[prototype]]

function logContent(){}
logContent --> Function --> Object --> null

Prototypal Inheritance

..if a property or a method is not found in the object itself, then there is an attempt to find this property/method in the prototype chain.
Ref: Js - The Core

Design Patterns

A pattern is a reusable solution that can be applied to commonly occurring problems in software design - in our case - in writing JavaScript web applications.
Ref: What is a Design Pattern

Vad är ett mönster?

Problem: Jag måste skapa jättemånga olika objekt som följer samma struktur.

function Country(name, population){
  this.name = name;
  this.population;
}

Lösning: Jag skapar en funktion som skapar objektet åt mig.

Problem: Jag måste gruppera ett antal funktioner som logiskt hört samman.

var CountryDatabase = {
  dataAboutCountries: [],
  functionUsingTheData : function(){
  }
}
function functionThatDoesNotUseTheData(){
  //I'm a function that does another thing
}
Pattern

Användningsområden

När ska jag använda vad?

"Ugh, hittar ingenting och jag har döpt massa grejer till samma sak så jag är osäker på vilken kod jag kallar på."

Du behöver troligen strukturera din kod bättre, t.ex. med beprövade metoder.

Samma som med allt annat: behöver inte följas strikt, de är bara hjälpmedel.

Oberoende av språk

Oberoende av programmeringsspråk har nästan alla samma sort problem: svårt att lägga upp koden.

Du kommer stöta på samma sorts mönster i andra språk men med olika implementationer: språk som är lika varandra har liknande problem.

Jag tar upp några JavaScript-implementationer som man kan använda sig av.

Constructor Pattern

function Person(name, age, vegan){
  this.name = name;
  this.age = age;
  this.vegan = vegan;
}

Vi har ju flera olika sätt att skapa objekt, Constructor pattern är ett av dessa vi kan använda.

Person.prototype.isVegan = function(){
  return this.vegan;
}
Person.prototype.sayName = function(){
  console.log("I'm " + this.name);
}

Det skapas ett prototype-objekt som är kopplat till varje nytt objekt.

Ärvda properties

Prototype Pattern

var prototype = {
  prototypeFunction: function(){
    console.log("Hello from prototype!");
  }
}
var a = Object.create(prototype);

Vi skapar ett objekt baserat på ett annat objekt, ärver det första objektets funktioner.

Behöver inte instansiera med new

Constructor vs. Prototype Pattern

Använd den som känns mest logisk för dig

Med Object.create måste man skapa en egen constructor

Människor som är true till JavaScript brukar förespråka att man inte ska använda new t.ex.

Båda utför jobbet, välj den som gör jobbet enkelt för dig.

Immedietly-invoked Function Expression

IIFE Ref: Wiki - IIFE

IIFE

(function(){
  console.log("I run and log directly!");
  console.log("I don't have to be called by you!");
  console.log("Praise our robot overlords");
})();

IIFE

(function(){
  return "I get returned but not saved :(";
})();
var saved = (function(){
  return "Yay, I now exists in the variabel 'saved'";
})();

IIFE

Använd när du behöver skapa closures för att bevara variabler

Använd när du har kod som t.ex. ska kallas på automatisk: init-funktion

Funktionen körs direkt efter att den är skapad

Ligger den däremot inuti en annan funktion körs den inte förän den yttre funktionen kallas på

Parameters

(function(param){
  console.log(param + ' So anonymous!');
})("Wow!");
//"Wow! So anonymous!"
(param => {
  console.log(param + ' So anonymous!');
})("Wow!");
//"Wow! So anonymous!"

Module Pattern

Problem:All min kod är tillgänglig överallt. Jag vill följa Principle of Least Privilege

var obj = {
  importantProp: "importantValue"
};
obj.importantProp = "";

Inte så viktig längre

Object.defineProperty(obj, 'importantProp',{});

Omständligt och vi kanske vill ändra värdet i framtiden.

Vi vill kunna skriva över värdet, men det ska inte kunna ske av misstag.

Module Pattern

Nick Young Confused
var Module = (function(){
  var importantProp = "importantValue";
  return {
    getImportantValue: function(){
      return importantValue;
    }
  }
})();

En IIFE som direkt returnerar ett objekt. importantProp finns bara i en closure

Revealing Module Pattern

Revealing Module Pattern

Revealing module pattern är en variant på Module Pattern

Vi får här välja vilka funktioner och variabler som blir revealed: synliga för resten av koden

Privata funktioner kan heta något helt annat än publika funktioner

Nick Young Confused Nick Young Confused Nick Young Confused Nick Young Confused
var Module = (function(){
  var importantProp = "importantValue";
  var getImportantValue = function(){
      return importantValue;
  }
  return {
    getIt: getImportantValue
  }
})();

I objektet som returneras så väljer vi vad vi ska returnera och efter vilket namn

Namespaces

Namespaces can be considered a logical grouping of units of code under a unique identifier.
var namespace = {
  prop: val
}
namespace.prop === val
In JavaScript, they help us avoid collisions with other objects or variables in the global namespace. They're also extremely useful for helping organize blocks of functionality in a code-base so that it can be more easily referenced and used.
Ref: Namespacing Patterns

Koden vi arbetar med är inte alltid vår egen kod

Det är inte alltid lätt att få en överblick över vad som är deklarerat redan.

När man använder bibliotek eller plugins t.ex.

Namespacing any serious script or application is critical as it's important to safeguard our code from breaking in the event of another script on the page using the same variable or method names we are.
Ref: Namespacing Patterns

Namspacing Pattern

Object Literal, Module Pattern och Revealing Module Pattern är olika mönster för att hantera namespaces

Constructor & Protoypes är olika mönster för att skapa objekt

Allt använder sig av objekt och prototyper, scope och context.

Övning

Implementera Module Pattern och Revealing Module Pattern