Hoppa till innehåll

Utmaningar

Nedan finns ett antal program, försök läsa koden och se vad som kommer att skrivas ut.

Varje fråga har ett antal alternativ att välja bland för att göra det lite lättare att resonera. Klicka på “Visa lösning” för att se svaret och förklaringen.

Om du inte lyckas så kan du alltid prova koden och köra den på egen hand för att se vad som händer, eller ta upp frågan på en handledning.

Försök läsa koden, följ vad som sker och försök se vad som skrivs ut.

const run = function (first, last) {
return {
firstName: first,
lastName: last,
}
}
let result = run('Ellen', 'Nu')
console.log(result.last)
  1. [object Object]
  2. Ellen Nu
  3. Nu
  4. undefined

Svaret är alternativ 4, undefined. Objektet har egenskapen lastName, inte last. Att läsa en egenskap som inte existerar på objektet returnerar undefined.

const createMovie = (title, length, year) => {
return {
title,
length,
year,
}
}
const movies = []
movies.push(createMovie('Pulp Fiction', '2:34', '1994'))
movies.push(createMovie('The Shawshank Redemption', '2:22', '1994'))
movies.push(createMovie('The Godfather', '2:55', '1972'))
console.log(movies[1].length)
  1. 3
  2. 2:34
  3. 2:22
  4. undefined

Svaret är alternativ 3, 2:22. movies[1] är det andra objektet i arrayen och dess egenskap length har värdet '2:22' — filmens längd. Slamkryparen är att length vanligtvis ger antal element, men här är det en vanlig objektegenskap med ett strängvärde.

const objPrototype = {
prop: 10,
toString() {
return `I have ${this.prop} somethings!`
},
}
const createObject = function (quantity = 0) {
const obj = Object.create(objPrototype)
obj.prop = quantity
return obj
}
const obj = createObject(12)
console.log(obj.toString())
  1. I have 12 somethings!
  2. I have 10 somethings!
  3. I have 0 somethings!
  4. undefined

Svaret är alternativ 1, I have 12 somethings!. obj.prop = quantity skapar en egen egenskap på obj som skuggar prototypens prop. När toString() körs refererar this.prop till den egna egenskapen med värdet 12.

Fråga 05-04: Är funktionen “run” en funktion utan sidoeffekter? (Pure function)

Section titled “Fråga 05-04: Är funktionen “run” en funktion utan sidoeffekter? (Pure function)”
const run = function (obj) {
obj.quantity += 10
}
  1. Ja
  2. Nej
  3. Det beror på
  4. Kanske

Svaret är alternativ 2, Nej. Funktionen modifierar egenskapen quantity på det objekt som skickas in. Eftersom objekt skickas som referens i JavaScript, påverkas det ursprungliga objektet — det är en sidoeffekt.

const myObj = {
quantity: 12,
name: 'Part1',
}
const run = function (obj) {
obj.quantity += 10
}
run(myObj)
console.log(myObj.quantity)
  1. 12
  2. undefined
  3. 10
  4. 22

Svaret är alternativ 4, 22. myObj skickas som referens och parametern obj pekar på samma objekt. obj.quantity += 10 ändrar egenskapen direkt på myObj, vilket syns när vi läser myObj.quantity efteråt.

let quantity = 12
const run = function (q) {
q += 10
}
run(quantity)
console.log(quantity)
  1. 12
  2. undefined
  3. 10
  4. 22

Svaret är alternativ 1, 12. Talet quantity är en primitiv värdetyp och kopieras när det skickas som argument. Parametern q är en kopia — att ändra q påverkar inte quantity. run är i detta fall en funktion utan sidoeffekter.

const run = function () {
const objects = [
{ name: 'Ellen', points: 13 },
{ name: 'Sture', points: 3 },
{ name: 'Maja', points: 39 },
]
return objects.filter(function (current) {
return current.points < 10
})
}
let result = run()
console.log(result)
  1. ["Ellen", "Sture", "Maja"]
  2. [{name: "Ellen", points: 13}, {name: "Sture", points: 3}, {name: "Maja", points: 39}]
  3. { name: 'Sture', points: 3 }
  4. [ { name: 'Sture', points: 3 } ]

Svaret är alternativ 4, [ { name: 'Sture', points: 3 } ]. filter returnerar en ny array med de element för vilka callback-funktionen returnerar true. Här är current.points < 10 sant enbart för Sture (3 poäng).

Iteratorfunktioner som filter, map och reduce lämpar sig väl att kombinera med pilfunktioner:

const run = function () {
const objects = [
{ name: 'Ellen', points: 13 },
{ name: 'Sture', points: 3 },
{ name: 'Maja', points: 39 },
]
return objects.filter((current) => current.points < 10)
}
let result = run()
console.log(result)

Fråga 05-08: Hur många gånger kommer funktionen printTeachers() att anropas?

Section titled “Fråga 05-08: Hur många gånger kommer funktionen printTeachers() att anropas?”
let teachers = {
name: 'Mats',
next: {
name: 'Johan',
next: {
name: 'Niklas',
prev: {
name: 'Tobias',
},
},
},
}
function printTeachers(current) {
console.log(current.name)
if (current.next !== undefined) {
printTeachers(current.next)
}
}
printTeachers(teachers)
  1. 1
  2. 3
  3. 4
  4. Tills applikationen kraschar (evighetsloop)

Svaret är alternativ 2, 3. printTeachers anropas med teachers (Mats), sedan rekursivt med Johan (Mats’s next) och en gång till med Niklas (Johans next). Niklas saknar next, så rekursionen stannar. Tobias nås aldrig — han är länkad via prev, inte next.

const frequencyTable = {
abyssinian: 12,
bombay: 2,
bengal: 14,
burmese: 2,
'main coon': 4,
}
for (key of Object.keys(frequencyTable)) {
console.log(frequencyTable[key])
}
  1. abyssinian, bombay, bengal, burmese, main coon
  2. 12, 2, 14, 2, 4
  3. 34
  4. Applikationen kraschar (evighetsloop)

Svaret är alternativ 2, 12, 2, 14, 2, 4. Object.keys(frequencyTable) returnerar en array med objektets nyckelnamn. Varje nyckel används sedan för att slå upp värdet via frequencyTable[key], så det är värdena som skrivs ut — inte nyckelnamnen.

Samma sak kan lösas med Object.values:

for (value of Object.values(frequencyTable)) {
console.log(value)
}

Eller med destrukturering via Object.entries:

for (const [catType, catQuant] of Object.entries(frequencyTable)) {
console.log(catType, catQuant)
}
CCBY