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 () {
const numbers = [1, 2, 3, 4, 5]
let length = numbers.length
return numbers[length]
}
let result = run()
console.log(result)
  1. undefined
  2. [1, 2, 3, 4, 5]
  3. 5
  4. 1

Svaret är alternativ 1, undefined. length är 5, så numbers[length] refererar till index 5 som inte finns i arrayen.

const run = function () {
const numbers = [1, 23, 13, 4, 8]
numbers.sort()
return numbers
}
let result = run()
console.log(result)
  1. [1, 13, 23, 4, 8]
  2. [1, 4, 8, 13, 23]
  3. [23, 13, 8, 4, 1]
  4. [1, 23, 13, 4, 8]

Svaret är alternativ 1, [1, 13, 23, 4, 8]. sort-funktionen sorterar lexikografiskt — den gör om samtliga nummer till strängar och sorterar dessa, därav att 13 kommer före 23 men efter 1.

För numerisk sortering behöver vi skicka med en jämförelsefunktion:

const run = function () {
const numbers = [1, 23, 13, 4, 8]
numbers.sort((a, b) => a - b)
return numbers
}
let result = run()
console.log(result)

Fråga 04-03: Vilka av funktionerna lämnar argumentet opåverkat?

Section titled “Fråga 04-03: Vilka av funktionerna lämnar argumentet opåverkat?”
// ------------------------------------------------------------------
let anArray = [2, 6, 8]
const functionA = function (hej) {
hej[hej.length] = 10
return hej
}
functionA(anArray)
anArray // is anArray still [2, 6, 8]?
// ------------------------------------------------------------------
anArray = [2, 6, 8]
const functionB = function (arr) {
const copy = Array.from(arr)
copy.push(10)
return copy
}
functionB(anArray)
anArray // is anArray still [2, 6, 8]?
// ------------------------------------------------------------------
anArray = [2, 6, 8]
let functionC = function (arr) {
return arr.map(Math.sqrt)
}
functionC(anArray)
anArray // is anArray still [2, 6, 8]?
// ------------------------------------------------------------------
let aNumber = 2
const functionD = function (nbr) {
nbr = nbr * nbr
return nbr
}
functionD(aNumber)
aNumber // is aNumber still 2?
  1. functionA
  2. functionB
  3. functionC
  4. functionD

Alternativ 2, 3 och 4 (functionB, functionC, functionD) lämnar argumentet opåverkat.

Funktion A (alternativ 1) — påverkar argumentet

Section titled “Funktion A (alternativ 1) — påverkar argumentet”

Arrayens referens skickas in som argument och parametern “hej” pekar på samma array som “anArray”.

graph TD
A[anArray] -->|refererar| B("[2, 6, 8]")
C[hej] -->|refererar| B

En förändring via “hej” påverkar därmed också “anArray”. Funktion A är en funktion med sidoeffekter.

Funktion B (alternativ 2) — lämnar argumentet opåverkat

Section titled “Funktion B (alternativ 2) — lämnar argumentet opåverkat”

En kopia av arrayen skapas med Array.from, och push görs på kopian.

graph TD
A[anArray] -->|refererar| B("[2, 6, 8]")
C[arr] -->|refererar| B
D[copy] -->|refererar| E("[2, 6, 8, 10]")

En kopia kan göras på flera sätt:

const copy = Array.from(arr)
const copy = [...arr]
const copy = arr.slice()

Funktion C (alternativ 3) — lämnar argumentet opåverkat

Section titled “Funktion C (alternativ 3) — lämnar argumentet opåverkat”

Array.map returnerar alltid en ny array och lämnar originalet oförändrat.

Funktion D (alternativ 4) — lämnar argumentet opåverkat

Section titled “Funktion D (alternativ 4) — lämnar argumentet opåverkat”

aNumber är ett tal — en primitiv datatyp av värdetyp. Argumentet kopieras till parametern, ingen manuell kopiering behövs.

graph TD
A[aNumber, 2]
C[nbr, 2]
const run = function () {
const arr = ['ett', 'två', 'tre', 'fyra', 'fem']
return arr.slice(2, 3)
}
let result = run()
console.log(result)
  1. [‘ett’, ‘två’, ‘tre’, ‘fyra’, ‘fem’]
  2. [‘två’, ‘tre’]
  3. [‘tre’]
  4. [‘tre’, ‘fyra’]

Svaret är alternativ 3, ['tre']. slice(start, end) returnerar element från och med index start upp till men inte inklusive index end. slice(2, 3) returnerar alltså bara elementet på index 2, vilket är 'tre'.

const run = function () {
const numbers = [-129, 123, 2, 3987]
let length = numbers.length
let x = numbers[0]
for (let i = 1; i < length; i++) {
if (numbers[i] > x) {
x = numbers[i]
}
}
return x
}
let result = run()
console.log(result)
  1. -129
  2. 123
  3. 2
  4. 3987

Svaret är alternativ 4, 3987. Funktionen hittar det största värdet i arrayen. Variabelnamnet x försvårar läsningen — med ett bättre namn syns avsikten tydligare:

const run = function () {
const numbers = [-129, 123, 2, 3987]
let length = numbers.length
let max = numbers[0]
for (let i = 1; i < length; i++) {
if (numbers[i] > max) {
max = numbers[i]
}
}
return max
}
let result = run()
console.log(result)

Ett kortare alternativ med spridningsoperatorn:

const run = function () {
const numbers = [-129, 123, 2, 3987]
return Math.max(...numbers)
}
let result = run()
console.log(result)

(Undvik Math.max(...numbers) för arrayer med fler än ~30 000 element — det leder till ett stack overflow-fel.)

const addOddNumber = (arr, value) => {
if (typeof value !== 'number' || Number.isNaN(value)) {
throw new TypeError('Value must be of type Number')
}
if (value % 2 === 0) {
throw new Error('Value must be an odd number')
}
arr.push(value)
return arr
}
try {
let result = addOddNumber([3, 7, 1, 11], 12)
console.log(result)
} catch (e) {
console.log(e)
}
  1. Value must be of type Number
  2. [3, 7, 1, 11, 12]
  3. Error: Value must be an odd number
  4. 5

Svaret är alternativ 3. 12 % 2 === 0 är sant (12 är ett jämnt tal), så throw new Error('Value must be an odd number') körs. Undantaget fångas av catch (e) och console.log(e) skriver ut Error-objektet.

CCBY