Functions Flashcards
Omdat functies achter de schermen objecten zijn, hebben ze een aantal eigenschappen en methoden. Een van deze eigenschappen is de this eigenschap.
De this eigenschap wordt geïnitialiseerd wanneer de functie wordt opgeroepen. De waarde die aan this wordt gebonden is afhankelijk van de manier waarop de functie wordt opgeroepen. Geef aan wat deze manieren zijn (er zijn er 3) en wat in dit geval de waarde van this is.
Als de functie die wordt opgeroepen een gewone (globale of lokale) functie is, dan zal this gelijk zijn aan “undefined” in strict mode en gelijk zijn aan het globaal object (het window object) in ‘sloppy’ mode.
Als de functie die wordt opgeroepen een methode van een object is, dan zal this verwijzen naar het object dat die methode heeft opgeroepen.
Arrow functies hebben geen this eigenschap. Dit wilt zeggen dat, Indien de arrow functie wordt opgeroepen en deze arrow functie het this keyword gebruikt in zijn body, dan zal deze this de waarde bevatten van de parent van de arrow functie.
Wat is de output van de volgende code en verklaar:
// object
const video = {
title: “a”,
tags: [“a”, “b”, “c”],
showTags() { this.tags.forEach(function (tag) { console.log(this.title, tag); }); }, };
//oproep van methode
video.showTags();
In normal mode is de output:
undefined 'a' undefined 'b' undefined 'c'
Dit is omdat in normal of ‘sloppy’ mode, de this waarde voor de callback functie gelijk is aan het window object. Omdat dit window object geen title eigenschap bevat, zal this.title resulteren in undefined.
In strict mode zal de deze code resulteren in een foutmelding. Dit is omdat in strict mode this gebonden zal worden aan undefined. this.title zal daarom ook resulteren in een foutmelding.
Omdat functies achter de schermen objecten zijn, hebben ze een aantal eigenschappen en methoden.
Drie van deze methoden hebben betrekking op de this eigenschap van de functie, namelijk: call, apply en bind.
Waarvoor dienen deze methoden en wat is het verschil tussen deze drie?
Alle drie methoden hebben als doel om de this waarde van de functie te initialiseren met de waarde dat wordt meegegeven als argument van de methoden. Bijvoorbeeld, stel we hebben de volgende functie:
function playVideo(x, y, z) {
console.log(this, x, y, z);
}
Als we nu bij oproep van de functie, de waarde voor this willen binden aan een bepaalde waarde (zoals bijvoorbeeld een object, dan kan dit aan de hand van call en apply:
playVideo.call({ name: “Jimmy” }, 1, 2, 3);
playVideo.apply({ name: “Jimmy” }, [1, 2, 3]);
beide methoden gaan de functie oproepen en hun this waarden binden aan de waarde dat als eerste argument wordt meegegeven. Merk op dat na het eerste argument van beide methoden een lijst van argumenten wordt meegegeven die zal doorgegeven worden aan de functie playVideo.
Hier zie je ook meteen het verschil tussen call en apply, namelijk: apply neemt deze argumenten mee als een array terwijl dit bij call niet moet.
De bind methode doet net hetzelfde als de call methode met als verschil dat het de functie playVideo niet meteen zal oproepen. Het is daarom ook niet nodig om de argumenten voor playVideo mee te geven aan de bind methode:
const foo = playVideo.bind({ name: “Jimmy” });
foo(1, 2, 3);
Hoe kan je een functie definiëren die een oneindig aantal argumenten kan hebben?
Er zijn twee manieren om dit te doen:
1. Door gebruik te maken van het argument object:
function sum() {
let sum = 0;
for (let val of arguments) {
sum += val;
}
return sum;
}
Merk op dat we de for-of loop normaal gebruiken om door een array te lopen maar dat we het in dit geval gebruiken om door een object te lopen. In normale omstandigheden zou dit niet gaan omdat gewone objecten geen iterable zijn. In dit geval gaat het echter wel omdat het arguments object een speciaal object is dat een iterable object wordt genoemd. Iterable objecten zijn objecten waarvoor een Symbol.iterator is gedefinieerd in hun body.
Belangrijk om te weten is dat arrow functies geen arguments object bevatten.
- Door gebruik te maken van de rest operator:
// de rest operator zal alle argumenten budnelen in een array met
// de naam values.
function sum(…values) {
let sum = 0;
for (let val of values) {
sum += val;
}
return sum;
}
wat ook kan is het volgende:
function TotalPrice(discount, …prices) {
}
In dit geval is het belangrijk dat de rest parameter altijd als laatste in de parameterlijst moet staat.
Hoe kan je default waarden voor de parameters van een functie definiëren?
Volgend voorbeeld laat zien hoe dit moet:
function calcInterest(lone, rate = 3.5, years = 5) {
return ((lone * rate) / 100) * years;
}
Belangrijk bij deze aanpak is dat wanneer je 1 parameter een default waarde geeft, dat alle parameters na deze parameter ook allemaal een default waarde moeten hebben. anders gezegd, parameters met default waarden komen altijd achteraan de parameterlijst.
- Wat zijn closures? Geef een voobeeld.
Een closure is de bundeling van een functie en de toestand van de omgeving waarbinnen deze functie is aangemaakt. M.a.w. wanneer een functie wordt gedefinieerd, dan zal de functie ook de variabelen die in dezelfde omgeving zijn gedefinieerd onthouden. Volgend voorbeeld toont dit aan:
function foo() {
let ctr = 0;
return function () {
console.log(++ctr );
};
}
const faa = foo();
faa();
Hier merken we dat faa nog steeds toegang heeft tot de variabele ctr, ookal is de functie foo al reeds uitgevoerd, waardoor het van de callstack is gehaald, en waardoor de ctr variabele niet meer zou moeten bestaan.
Functies in javascript zijn eerste klas. Wat betekent dit?
Eerste klasse functies zijn functies die:
- We kunnen voorzien van een naam.
- We kunnen gebruiken als input van een andere functie.
- We kunnen teruggegeven als output van een andere functie.
- Wat zijn hogere orde functies?
- Welke feature met betrekking op functies moet de programmeertaal bezitten om hogere orde functies te kunnen definiëren?
- Wat is het voordeel van hogere orde functies?
- Hogere orde functies zijn functies die:
- een functie nemen als input
- een functie produceren als output. - Hogere orde functies zijn enkel mogelijk indien functies eerste klas zijn.
- Hogere orde functies zijn belangrijk omdat ze ervoor zorgen dat we meer abstractie kunnen toepassen. Denk bijvoorbeeld aan een functie die over een array van waarden moet itereren en iets moet doen met deze waarden. We kunnen dan een hogere orde functie implementeren die over de array loopt en die een functie toepast op deze verschillende elementen van de array.
Wat is het verschil tussen een functie declaratie en een functie expressie?
Een functie declaratie en expressie hebben de volgende verschillen:
- de implementatie:
de implementatie van een functie declaratie:
function foo(){
// body
}
De implementatie van en functie expressie:
const foo = function(){
// body
};
- Functie expressies worden niet gehoïst. Ze kunnen dus niet gebruikt worden op een plaats dat voor hun definitie komt.
- Functie expressies worden niet aan het window object toegevoegd.
- Wat is een anonieme functie?
- Wat is de use-case voor het gebruik van anonieme functies?
- Hoe kan je een anonieme functie bij zijn definitie meteen oproepen?
- Hoe noem je functies die meteen na hun definitie opgeroepen worden?
1.Een functie zonder naam.
- use-cases:
- Wanneer we ze willen gebruiken als een waarde. Denk bijvoorbeeld aan wanneer we functie expressies definiëren.
- Wanneer we ze willen gebruiken als expressies. (expressies geven een waarde terug).
- Wanneer we ze willen doorgeven als argument (denk aan callback functies).
- wanneer we ze willen teruggeven als output van een functie. - Je kan een anonieme functie als volgt meteen oproepen:
(function () {
console.log(“Hello”);
})();
- Functies die meteen worden opgeroepen nadat ze zijn gedefinieerd worden Immediatly Invoked Function Expressions (IIFE’s) genoemd.
- Wat zijn arrow functies? Geef een voorbeeld.
- Wat kan je zeggen over het this keyword van arrow functies?
- Een arrow functie is een verkorte vorm van een functie expressie. Om dit duidelijk te maken vertrekken we vanuit de volgende functie expressie:
const calcAge = function(birthYear){
return 2037 - birthYear;
}
Deze functie gïmplementeerd als een arrow functie ziet er als volgt uit:
const calcAge = birthYear => 2037 - birthYear;
Merk op dat het niet nodig is om het return keyword in de arrow functie te plaatsen.
- Arrow functies bezitten geen this keyword. Dit wilt zeggen dat, als ze het this keyword in hun body hebben staan, dat deze this waarde zal refereren naar de this waarde van de parent functie van de arrow functie.
Een globale functie declaratie wordt steeds toegevoegd aan het window object. Zaken toevoegen aan het window object is echter afgeraden. Hoe kan je vermijden dat functies worden toegevoegd aan dit globaal object?
Door de functies te definiëren als functie expressies.