Javascript Boekenclub - kosterm14/portfolio GitHub Wiki
David heeft een bericht gestuurd in de FDND Agency teams chat dat hij een Javascript boekenclub wil beginnen. Hij wil het boek "You Don't Know JS Yet: Get Started" van Kyle Simpson gaan lezen en bespreken.
Ik ben zelf totaal niet goed genoeg in Javascript en denk er aan om lid te worden van de club. Ik kan deze Javascript kennis goed gebruiken en als David me hier mee kan helpen door het samen met me te leren is dat een leuke bonus.
Joost gaf vandaag een presentatie over het progressively enhancen van formulieren. Hier kwam ook Javascript bij kijken en ik merkte vandaag echt hoe weinig ik hier eigenlijk van weet. Hij had het over allemaal termen als hoisting en scopes waar ik nooit van gehoord heb.
Ik heb David vandaag benaderd om deel te worden van de boekenclub. Ik ben blijkbaar de eerste die zich aangesloten heeft. Ik heb met David afgesproken om elke week een meeting te houden voor de boekenclub waarin we samen door het boek gaan en bespreken wat we de voorafgaande week geleerd hebben.
Vandaag was de eerste club meeting! Ik ging met David en nieuwe leden Badr, Rayan en Danique het boek bespreken. In het boek informeert auteur Kyle Simpson de lezer over wat Javascript nou precies is en worden de basics uitgelegd. We gingen gezamelijk door de hoofdstukken lezen en hebben hier veel van opgestoken.
De naam Javascript is eigenlijk gewoon een marketing truc! Toen de bedenker Brendan Eich de taal bedacht had het project de code-naam Mocha. Maar toen de tijd kwam om een echte naam te kiezen werd er gekozen voor Javascript, waarom is dat? De initiële doelgroep was eigenlijk grotendeels Java programmeurs en het woord script was in die tijd een populair woord om te verwijzen naar light weight programma's.
Het gebruik van dubbele of enkelvoudige quotation marks maakt geen verschil voor de werking van je code. Wel is er een verschil in wat back-ticks doen. Hieronder heb ik een voorbeeld uit het boek gehaald. In onderstaand voorbeeld is te zien dat bij het gebruik van zowel dubbele als enkelvoudige quotation marks de string letterlijk overgenomen wordt. Bij het gebruik van back-ticks word de firstName variabel wel de value Kyle gegeven. (Dit heeft interpolation)
console.log("My name is ${ firstName }.");
// My name is ${ firstName }.
console.log('My name is ${ firstName }.');
// My name is ${ firstName }.
console.log(`My name is ${ firstName }.`);
// My name is Kyle.
Hieronder heb ik een voorbeeld uit het boek gehaald over het verschil tussen var en let. De name is hier een var en de age is hier een let. Zoals je kunt zien is alleen de name op te halen in de console.log en krijg je een error als je de age wilt weergeven. Waarom is dit? Een let is meer limited dan een var, dit heet block scoping. De let was geblock-scoped in de if statement terwijl de var dat niet is. Hierdoor kun je de var wel console.loggen buiten de if statement maar de let niet.
Dit klinkt als een nadeel maar dit kan ook erg handig zijn als je bijvoorbeeld meerdere variabelen hebt met dezelfde naamgeving. Je kunt deze dan block-scopen zodat je ze niet door elkaar haalt.
var adult = true;
if (adult) {
var name = "Kyle";
let age = 39;
console.log("Shhh, this is a secret!");
}
console.log(name);
// Kyle
console.log(age);
// Error!
We kunnen const natuurlijk niet vergeten! Een const is net als een let maar dan met nog een extra limitatie; je moet een const op declaratie een waarde geven en deze waarde kan je niet re-assignen.
Hieronder is een voorbeeld uit het boek te zien. Je kunt hier zien dat de const myBirthday een waarde krijgt van true bij declaratie. Er wordt geprobeerd de waarde van deze boolean hierna te re-assignen en dit kan niet met een const. Hier komt dus een error uit.
const myBirthday = true;
if (myBirthday) {
myBirthday = false; // Error!
}
Een interessant kenmerk van const is dat je de waarde wel kunt veranderen, je kunt het alleen niet re-assignen. Wat betekent dit? Hieronder is een voorbeeld uit het boek te vinden. In onderstaand voorbeeld worden twee dingen geprobeerd.
Allereerst wordt actor[2] toegevoegd aan de array. Dit is een verandering aan de const die er niet voor zorgt dat een bestaande waarde in deze const ge re-assigned wordt aangezien er alleen een actor[0] en een actor[1] in de array zitten op declaratie. Dit kan!
In de tweede wijziging wordt er geprobeerd de data in de array te veranderen naar [ ] (niks dus, het wordt een lege array). Dit zou de waarden van actor[0] en actor[1] wijzigen en dus re-assignen. Dit kan niet!
const actors = [
"Morgan Freeman", "Jennifer Aniston"
];
actors[2] = "Tom Cruise"; // OK :(
actors = []; // Error!
In simpele woorden: Je kunt dingen toevoegen, maar niet verwijderen of wijzigen.
Dit hebben we niet gezamelijk besproken maar ik vroeg me zelf gewoon af wat het betekende dus ik heb het na de club meeting nog even onderzocht. Hoisting is een Javascript mechanisme wat ervoor zorgt dat variabelen en functie declaraties naar de top van de scope verplaatst worden voordat de code execute.
In onderstaand voorbeeld zie je een functie genaamd testFunctie die ervoor zal zorgen dat "text" geconsole logged wordt. Je Javascript code wordt van boven naar beneden gelezen dus hoe kan het dat je een functie kan aanroepen voordat deze bestaat? Dit is dus wat hoisting is. De functie declaratie van de testFunctie wordt verplaatst naar de top van de scope voordat de code execute zodat de functie wel bestaat en deze kun je hierna dus gewoon oproepen.
testFunctie();
// text
function testFunctie() {
console.log("text");
}
We gingen vandaag weer samenzitten voor de tweede Javascript club meeting. De nieuwe leden Ivar, Trisjan en Duneya deden vandaag ook mee. We gingen gezamelijk verder waar we vorige week gebleven waren. Deze week was wat technischer dan de vorige en dus wat moeilijker te begrijpen, maar doordat we elkaar constant hielpen en dingen aan elkaar uit aan het leggen waren tijdens het lezen zijn we er toch door gekomen.
Ik ben er tijdens het schrijven van de week 2 notes achter gekomen dat hoisting wat dieper is dan ik eerst dacht. Hoisting werkt niet met let en const. Ze worden wel naar de top van de scope verplaatst maar komen terecht in een "temporal dead zone". Hoisting is dus alleen voor var en functie declaraties. Wel moet je erop letten dat deze twee soorten hoisting beide net iets anders werken.
In onderstaande code heb ik het voorbeeld van hoisting part 1 gekopieerd. Hoisting met functies werkt gewoon zoals we al kennen. De functie declaratie wordt naar de top van de scope verplaatst en deze kun je hierna dus gewoon oproepen.
testFunctie();
// text
function testFunctie() {
console.log("text");
}
Dit werkt echter net iets anders voor het hoisten van variabelen. In onderstaand voorbeeld probeer ik de var x te console loggen voordat deze gedeclareerd is net zoals ik deed in het function hoisting voorbeeld hierboven. Dit werkt echter niet in dit geval. Dit komt omdat alleen de declaratie van de variabel wordt gehoist, niet de initialisatie.
console.log(x) // undefined
var x = 1;
Wat betekent dit? Declaratie is het maken van de variabel, initialisatie is het geven van een waarde aan deze variabel. In onderstaand voorbeeld is de declaratie dus 'var x;' en is de initialisatie 'x = 1;'. Zoals eerder gezegd wordt alleen de declaratie gehoist en niet de initialisatie. Je moet er dus voor zorgen dat de initialisatie al bovenaan staat want deze zal niet voor je verplaatst worden.
In het bovenstaande voorbeeld worden de declaratie en de initialisatie in dezelfde regel gedaan. Omdat alleen de declaratie gehoist wordt zorgt dit ervoor dat er geen initialisatie is op het moment dat de console.log aangeroepen wordt. De x waarde is dus niet geinitialiseerd en is dus undefined. In het onderstaande voorbeeld heeft de x wel een waarde omdat de initialisatie bovenaan de scope staat geschreven en de declaratie naar de top van de scope gehoist wordt.
x = 1; (initialisatie)
console.log(x) // 1
var x; (declaratie)
Naast de bekende var, let en const zijn er ook andere syntax die variabelen declareren. Voorbeelden hiervan zijn function en catch.
In onderstaand voorbeeld uit het boek is te zien dat function de identifier (voor een uitleg van wat een identifier is lees door) 'hello' declareerd met de parameter name. Een parameter is eigenlijk een local variable in de functie. Deze parameter bestaat alleen in de functie waarin hij gemaakt is en zal dus alleen bruikbaar zijn in de functie hello. We hebben bij de let uitleg van week 1 al eerder gehoord van block scoping en hier gebeurd bijna hetzelfde, nu is het echter function scoping omdat het in een functie gebeurt. De identifier hello zal zich daarintegen voordoen alsof het gedeclareerd werd in een var en is wel overal bruikbaar.
function hello(name) {
console.log(`Hello, ${ name }.`);
}
hello("Kyle");
// Hello, Kyle.
In nog een voorbeeld uit het boek hieronder is te zien dat catch het variabel 'err' declareerd. Dit variabel is block scoped en bestaat alleen in de catch. Net alsof het door een let gedeclareerd was.
try {
someError();
}
catch (err) {
console.log(err);
}
In het 'Andere vormen van declaratie' gedeelte gebruik ik opeens het woord identifier maar wat is dit nou eigenlijk? Het boek legt dit niet goed genoeg uit maar ik heb hier zelf wat onderzoek naar gedaan. het verschil tussen identifiers en variables is heel vaag en onbelangrijk en je kunt dit stuk eigenlijk gewoon negeren maar als je het toch wilt weten lees door I guess.
Het verschil tussen identifiers en variables is ongeveer hetzelfde als het verschil tussen namen en mensen. In onderstaand voorbeeld is 'totaal' de identifier van de variable die de totale waarden van x + y bevat. Het is basically hetzelfde, maar het is dus ongeveer de naam van de variabel die de waarde bevat. De naam van de persoon. De persoon en zijn naam zijn hetzelfde maar eigenlijk anders als je begrijpt wat ik bedoel. Jij bent je naam niet, je naam is een identifier van jou als persoon. Ook al zijn ze beide hetzelfde.
let x = 5;
let y = 10;
let totaal = x + y;
We zijn al bekend met functions declarations zoals het voorbeeld hieronder.
function add(a, b) {
return a + b;
}
console.log(add(2, 3)); // Outputs: 5
Hiernaast heb je ook dingen genaamd function expressions. In het voorbeeld hieronder is de function expression met de identifier 'function' te zien die geassigned is aan de const add.
const add = function(a, b) {
return a + b;
};
console.log(add(2, 3)); // Outputs: 5
Zoals je ziet werken ze beide gewoon hetzelfde. Waarom zou ik dan ooit een function expression gebruiken?
Hieronder zijn een paar verschillen:
- Function expressions worden niet gehoist (function declarations wel). Dit kan handig zijn om code beperkt te houden in een specifiek gedeelte van je code.
- Function expressions laten je functies toevoegen aan variabelen.
- Function expressions zorgen ervoor dat je functies kunt maken voor eenmalig gebruik.
Ik ga een voorbeeld laten zien van hoe eenmalige functies zouden werken met function expressions omdat dat me een erg handig voordeel lijkt.
Hieronder is hoe je een message zou maken met een normale function declaration. Je moet helemaal een showMessage functie aanmaken die je maar 1x gaat gebruiken.
function showMessage() {
console.log("Dit bericht verschijnt na 2 seconden");
}
setTimeout(showMessage, 2000);
Hieronder is hoe je een message zou maken met een function expression. Je hoeft de functie niet eens een naam te geven en zal hem hierna nooit meer gebruiken.
setTimeout(function() {
console.log("Dit bericht verschijnt na 2 seconden");
}, 2000);
Ik moet eerlijk toegeven dat ik function expressions nog niet helemaal snap maar ik zie wel in hoe het handig zou kunnen zijn tegenover function declarations.
Single-equals zijn er om waarden aan variabelen te geven.
var x = 5;
Double-equals worden gebruikt voor een vergelijking met 'loose-equality'. Deze vergelijking is zoals de naam aanduidt niet heel strict. Er worden veel dingen achter de schermen gedaan zoals onder anderen het converten van strings naar numbers en true naar 1 (false naar 0). Hierdoor kunnen veel fouten voorkomen doordat soortgelijke waarden gezien worden als hetzelfde.
42 == "42"; // true
1 == true; // true
Triple-equals worden gebruikt voor een vergelijking met 'strict-equality'. Deze vergelijking is juist wel strict. Er zal hier niks geconvert worden achter de schermen en de waarden moeten dus gelijk zijn aan elkaar.
42 === "42"; // false
1 === true; // false
Er zijn twee special cases met deze strict equality comparisons. NaN (Not a Number) word niet als equal gezien met NaN en 0 wordt gezien als een equal van -0.
NaN === NaN; // false
0 === -0; // true
Om deze special cases te voorkomen kan gebruik gemaakt worden van de meest stricte versie van vergelijking, Object.is(). Een vergelijking met Object.is zal niet kijken of twee waarden gelijk zijn aan elkaar zoals de vorige comparisons. Object.is() zal kijken of de twee waarden hetzelfde zijn. Door deze strictheid kun je Object.is() zien als een quadruple-equals.
console.log(Object.is(NaN, NaN));
// true
console.log(Object.is(-0, 0));
// false
Voor het loopen van functies kun je een for loop gebruiken. Hierin kun je zelf bepalen hoeveel iteraties er zullen zijn door condities te bepalen waar de loop aan moet voldoen. Dit is handig voor een situatie waarin je een functie wilt blijven loopen tot een conditie niet meer klopt. Hieronder is een voorbeeld van een for loop uit het boek te vinden waarin een for loop 3 keer zal runnen.
- De let i is standaard 0
- Zolang de waarde van i lager is dan de lengte van de array (in dit geval 4) zal de loop doorgaan.
- Zolang de huidige waarde van arr lager is dan 500 zal de loop doorgaan. Dit is dus zolang i kleiner is dan 3 met de waarden in deze array.
- Elke keer dat de condities kloppen zal de waarde van i + 1 gaan.
Eerste iteratie:
- i = 0
- De lengte van de array is 4, 0 < 4
- De huidige waarde van arr is nu 1 (i = 0), 1 < 500
- Eerste iteratie compleet, i++ (i is nu 1)
Tweede iteratie:
- i = 1
- De lengte van de array is 4, 1 < 4
- De huidige waarde van arr is nu 10 (i = 1), 10 < 500
- Tweede iteratie compleet, i++ (i is nu 2)
Derde iteratie:
- i = 2
- De lengte van de array is 4, 2 < 4
- De huidige waarde van arr is nu 100 (i = 2), 100 < 500
- Derde iteratie compleet, i++ (i is nu 3)
Vierde iteratie:
- i = 3
- De lengte van de array is 4, 3 < 4
- De huidige waarde van arr is nu 1000 (i = 3), 1000 > 500
- Vierde iteratie niet gelukt, 1000 > 500
Deze for loop runt 3 keer dus.
var arr = [ "1", "10", "100", "1000" ];
for (let i = 0; i < arr.length && arr[i] < 500; i++) {
// will run 3 times
}
Naast = kent iedereen < en >. Kleiner dan en groter dan natuurlijk. Je kunt deze combineren in een <= en >= (kleiner dan of gelijk aan/groter dan of gelijk aan)
1 > 0
1 < 2
1 <= 1
1 <= 2
1 >= 1
1 >= 0
Simpel toch? In het geval van vergelijking met relational operators tussen twee strings kunnen echter rare dingen gebeuren. In onderstaand voorbeeld uit het boek is te zien dat y (9) groter dan x (10) is.
Hoe komt dit? In het geval van vergelijking tussen twee strings met relational operators zal er alleen gekeken worden naar het eerste karakter in de string. In dit geval zal er dus een vergelijking plaatsvinden tussen de unicode waarden van 1 (49) en 9 (57). 49 < 57 en hierdoor zal x < y dus true zijn.
var x = "10";
var y = "9";
x < y; // true, watch out!
Deze week was ik er met David, Ivar, Trisjan en Youssra. We besloten omdat dit de laatste meeting is, in plaats van het boek weer door te nemen, onze kennis te testen met een online Javascript test. We deden dit op een website genaamd leetcode en op w3schools.