diff --git a/1-js/09-classes/05-extend-natives/article.md b/1-js/09-classes/05-extend-natives/article.md
index 28b4c6eb6..683f077c4 100644
--- a/1-js/09-classes/05-extend-natives/article.md
+++ b/1-js/09-classes/05-extend-natives/article.md
@@ -1,12 +1,11 @@
+# Udvid indbyggede klasser
-# Extending built-in classes
+Indbyggede klasser som Array, Map kan også udvides.
-Built-in classes like Array, Map and others are extendable also.
-
-For instance, here `PowerArray` inherits from the native `Array`:
+I dette eksempel, arver `PowerArray` fra den indbyggede `Array`:
```js run
-// add one more method to it (can do more)
+// tilføj en ekstra metode til den (nu kan den lidt mere)
class PowerArray extends Array {
isEmpty() {
return this.length === 0;
@@ -21,20 +20,21 @@ alert(filteredArr); // 10, 50
alert(filteredArr.isEmpty()); // false
```
-Please note a very interesting thing. Built-in methods like `filter`, `map` and others -- return new objects of exactly the inherited type `PowerArray`. Their internal implementation uses the object's `constructor` property for that.
+Bemærk noget interessant. Indbyggede metoder som `filter`, `map` og andre -- returnerer nye objekter af præcis den arvede type `PowerArray`. Deres interne implementering bruger objektets `constructor`-egenskab til det.
+
+I eksemplet ovenfor,
-In the example above,
```js
arr.constructor === PowerArray
```
-When `arr.filter()` is called, it internally creates the new array of results using exactly `arr.constructor`, not basic `Array`. That's actually very cool, because we can keep using `PowerArray` methods further on the result.
+Når `arr.filter()` kaldes, vil den internt oprette det nye array af resultater ved hjælp af denne `arr.constructor`, ikke fra den underliggende `Array`. Det er praktisk, fordi vi kan fortsætte med at bruge `PowerArray`-metoderne på yderligere oprettede objekter.
-Even more, we can customize that behavior.
+Vi kan også tilpasse adfærden.
-We can add a special static getter `Symbol.species` to the class. If it exists, it should return the constructor that JavaScript will use internally to create new entities in `map`, `filter` and so on.
+Vi kan tilføje en speciel statisk getter `Symbol.species` til klassen. Hvis den eksisterer, skal den returnere konstruktøren, som JavaScript vil bruge internt til at oprette nye entiteter i `map`, `filter` og så videre.
-If we'd like built-in methods like `map` or `filter` to return regular arrays, we can return `Array` in `Symbol.species`, like here:
+Hvis vi gerne vil have, at indbyggede metoder som `map` eller `filter` skal returnere almindelige arrays, kan vi returnere `Array` i `Symbol.species`, som her:
```js run
class PowerArray extends Array {
@@ -43,7 +43,7 @@ class PowerArray extends Array {
}
*!*
- // built-in methods will use this as the constructor
+ // indyggede metoder vil bruge denne som konstruktør
static get [Symbol.species]() {
return Array;
}
@@ -53,37 +53,37 @@ class PowerArray extends Array {
let arr = new PowerArray(1, 2, 5, 10, 50);
alert(arr.isEmpty()); // false
-// filter creates new array using arr.constructor[Symbol.species] as constructor
+// filter opretter nyt array ved hjælp af arr.constructor[Symbol.species] som konstruktør
let filteredArr = arr.filter(item => item >= 10);
*!*
-// filteredArr is not PowerArray, but Array
+// filteredArr er ikke PowerArray, men Array
*/!*
alert(filteredArr.isEmpty()); // Error: filteredArr.isEmpty is not a function
```
-As you can see, now `.filter` returns `Array`. So the extended functionality is not passed any further.
+Som det ses vil `.filter` nu returnere `Array`. Så den udvidede funktionalitet bliver ikke videregivet.
-```smart header="Other collections work similarly"
-Other collections, such as `Map` and `Set`, work alike. They also use `Symbol.species`.
+```smart header="Andre samlinger arbejder på samme måde"
+Andre samlinger, såsom `Map` og `Set`, arbejder på samme måde. De bruger også `Symbol.species`.
```
-## No static inheritance in built-ins
+## Ingen statisk nedarvning i indbyggede objekter
-Built-in objects have their own static methods, for instance `Object.keys`, `Array.isArray` etc.
+Indbyggede objekter har deres egne statiske metoder, for eksempel `Object.keys`, `Array.isArray` etc.
-As we already know, native classes extend each other. For instance, `Array` extends `Object`.
+Som vi allerede ved så udvider indbyggede klasser hinanden. For eksempel, `Array` udvider `Object`.
-Normally, when one class extends another, both static and non-static methods are inherited. That was thoroughly explained in the article [](info:static-properties-methods#statics-and-inheritance).
+Normalt, når en klasse udvider en anden, arves både statiske og ikke-statiske metoder. Dette blev grundigt forklaret i artiklen [](info:static-properties-methods#statics-and-inheritance).
-But built-in classes are an exception. They don't inherit statics from each other.
+Men indbyggede klasser er en undtagelse. De arver ikke statiske metoder fra hinanden.
-For example, both `Array` and `Date` inherit from `Object`, so their instances have methods from `Object.prototype`. But `Array.[[Prototype]]` does not reference `Object`, so there's no, for instance, `Array.keys()` (or `Date.keys()`) static method.
+For eksempel nedarver både `Array` og `Date` fra `Object`, så deres instanser har metoder fra `Object.prototype`. Men `Array.[[Prototype]]` refererer ikke til `Object`, så der er ingen, for eksempel, `Array.keys()` (eller `Date.keys()`) statisk metode.
-Here's the picture structure for `Date` and `Object`:
+Her er billedet for `Date` og `Object`:

-As you can see, there's no link between `Date` and `Object`. They are independent, only `Date.prototype` inherits from `Object.prototype`.
+Som du ser her er der ingen sammenhæng mellem `Date` og `Object`. De er uafhængige, kun `Date.prototype` arver fra `Object.prototype`.
-That's an important difference of inheritance between built-in objects compared to what we get with `extends`.
+Det er en vigtig forskel i arv mellem indbyggede objekter og hvad vi får med `extends`.
diff --git a/1-js/09-classes/06-instanceof/1-strange-instanceof/solution.md b/1-js/09-classes/06-instanceof/1-strange-instanceof/solution.md
index d41d90edf..185543890 100644
--- a/1-js/09-classes/06-instanceof/1-strange-instanceof/solution.md
+++ b/1-js/09-classes/06-instanceof/1-strange-instanceof/solution.md
@@ -1,7 +1,7 @@
-Yeah, looks strange indeed.
+Ja, det er lidt mærkeligt.
-But `instanceof` does not care about the function, but rather about its `prototype`, that it matches against the prototype chain.
+Men `instanceof` bryder sig ikke om funktionen, men snarere om dens `prototype`, som den matcher mod prototype-kæden.
-And here `a.__proto__ == B.prototype`, so `instanceof` returns `true`.
+Og her er `a.__proto__ == B.prototype`, så `instanceof` returnerer `true`.
-So, by the logic of `instanceof`, the `prototype` actually defines the type, not the constructor function.
+Så, hvis man følger logikken for `instanceof`, så definerer `prototype` faktisk typen, ikke constructor-funktionen.
diff --git a/1-js/09-classes/06-instanceof/1-strange-instanceof/task.md b/1-js/09-classes/06-instanceof/1-strange-instanceof/task.md
index 5b8dc7de3..810592865 100644
--- a/1-js/09-classes/06-instanceof/1-strange-instanceof/task.md
+++ b/1-js/09-classes/06-instanceof/1-strange-instanceof/task.md
@@ -2,9 +2,9 @@ importance: 5
---
-# Strange instanceof
+# Underlig instanceof
-In the code below, why does `instanceof` return `true`? We can easily see that `a` is not created by `B()`.
+Se på koden nedenfor. Hvorfor returnerer `instanceof` værdien `true`? Vi kan tydelig se, at `a` ikke er oprettet af `B()`.
```js run
function A() {}
diff --git a/1-js/09-classes/06-instanceof/article.md b/1-js/09-classes/06-instanceof/article.md
index 00aee3376..5a2cf3de0 100644
--- a/1-js/09-classes/06-instanceof/article.md
+++ b/1-js/09-classes/06-instanceof/article.md
@@ -1,42 +1,42 @@
-# Class checking: "instanceof"
+# Tjek en klasse: "instanceof"
-The `instanceof` operator allows to check whether an object belongs to a certain class. It also takes inheritance into account.
+Operatoren `instanceof` tillader at tjekke om et objekt tilhører en bestemt klasse. Den tager også arv i betragtning.
-Such a check may be necessary in many cases. For example, it can be used for building a *polymorphic* function, the one that treats arguments differently depending on their type.
+Sådan en tjek kan være nødvendig i mange tilfælde. For eksempel kan den bruges til at bygge en *polymorfisk* funktion, som behandler argumenter forskelligt afhængigt af deres type.
-## The instanceof operator [#ref-instanceof]
+## instanceof operatoren [#ref-instanceof]
-The syntax is:
+Syntaksen er:
```js
obj instanceof Class
```
-It returns `true` if `obj` belongs to the `Class` or a class inheriting from it.
+Den returnerer `true` hvis `obj` tilhører `Class` eller en klasse som arver fra den.
-For instance:
+For eksempel:
```js run
class Rabbit {}
let rabbit = new Rabbit();
-// is it an object of Rabbit class?
+// er det et objekt der er skabt af Rabbit klassen?
*!*
alert( rabbit instanceof Rabbit ); // true
*/!*
```
-It also works with constructor functions:
+Det virker også med constructor funktioner:
```js run
*!*
-// instead of class
+// istedet for class
function Rabbit() {}
*/!*
alert( new Rabbit() instanceof Rabbit ); // true
```
-...And with built-in classes like `Array`:
+... og med indbyggede klasser som `Array`:
```js run
let arr = [1, 2, 3];
@@ -44,19 +44,19 @@ alert( arr instanceof Array ); // true
alert( arr instanceof Object ); // true
```
-Please note that `arr` also belongs to the `Object` class. That's because `Array` prototypically inherits from `Object`.
+Bemærk at `arr` også tilhører `Object`-klassen. Det er fordi `Array` prototypisk arver fra `Object`.
-Normally, `instanceof` examines the prototype chain for the check. We can also set a custom logic in the static method `Symbol.hasInstance`.
+Normalt undersøger `instanceof` prototype-kæden for tjekket. Vi kan også sætte en tilpasset logik i den statiske metode `Symbol.hasInstance`.
-The algorithm of `obj instanceof Class` works roughly as follows:
+Algoritmen for `obj instanceof Class` fungerer cirka sådan:
-1. If there's a static method `Symbol.hasInstance`, then just call it: `Class[Symbol.hasInstance](obj)`. It should return either `true` or `false`, and we're done. That's how we can customize the behavior of `instanceof`.
+1. Hvis der er en statisk metode `Symbol.hasInstance`, så kald den: `Class[Symbol.hasInstance](obj)`. Den skal returnere enten `true` eller `false`, og så er vi færdige. På den måde kan vi tilpasse adfærden for `instanceof`.
- For example:
+ For eksempel:
```js run
- // set up instanceof check that assumes that
- // anything with canEat property is an animal
+ // sæt et instanceof tjek der regner med
+ // at alt med en canEat egenskab er et dyr
class Animal {
static [Symbol.hasInstance](obj) {
if (obj.canEat) return true;
@@ -65,24 +65,24 @@ The algorithm of `obj instanceof Class` works roughly as follows:
let obj = { canEat: true };
- alert(obj instanceof Animal); // true: Animal[Symbol.hasInstance](obj) is called
+ alert(obj instanceof Animal); // true: Animal[Symbol.hasInstance](obj) kaldes
```
-2. Most classes do not have `Symbol.hasInstance`. In that case, the standard logic is used: `obj instanceof Class` checks whether `Class.prototype` is equal to one of the prototypes in the `obj` prototype chain.
+2. De fleste klasser har ikke `Symbol.hasInstance`. I det tilfælde bruges standardlogikken: `obj instanceof Class` tjekker om `Class.prototype` er lig med en af prototyperne i `obj`'s prototypekæde.
- In other words, compare one after another:
+ Med andre ord, sammenlign en efter en:
```js
obj.__proto__ === Class.prototype?
obj.__proto__.__proto__ === Class.prototype?
obj.__proto__.__proto__.__proto__ === Class.prototype?
...
- // if any answer is true, return true
- // otherwise, if we reached the end of the chain, return false
+ // hvis en af svarene er true, returner true
+ // ellers, hvis vi nåede enden af kæden, returner false
```
- In the example above `rabbit.__proto__ === Rabbit.prototype`, so that gives the answer immediately.
+ I eksemplet ovenfor `rabbit.__proto__ === Rabbit.prototype`, så det giver svaret øjeblikkeligt.
- In the case of an inheritance, the match will be at the second step:
+ I tilfældet af nedarvning vil matchningen være på det andet trin:
```js run
class Animal {}
@@ -99,70 +99,70 @@ The algorithm of `obj instanceof Class` works roughly as follows:
*/!*
```
-Here's the illustration of what `rabbit instanceof Animal` compares with `Animal.prototype`:
+Her er en illustration af hvad`rabbit instanceof Animal` sammenligner med `Animal.prototype`:

-By the way, there's also a method [objA.isPrototypeOf(objB)](mdn:js/object/isPrototypeOf), that returns `true` if `objA` is somewhere in the chain of prototypes for `objB`. So the test of `obj instanceof Class` can be rephrased as `Class.prototype.isPrototypeOf(obj)`.
+Forresten er der også en metode kaldet [objA.isPrototypeOf(objB)](mdn:js/object/isPrototypeOf), der returnerer `true` hvis `objA` er et eller andet sted i kæden af prototyper for `objB`. Så testen af `obj instanceof Class` kan omformuleres som `Class.prototype.isPrototypeOf(obj)`.
-It's funny, but the `Class` constructor itself does not participate in the check! Only the chain of prototypes and `Class.prototype` matters.
+Det er lidt morsomt, men `Class` konstruktøren deltager ikke selve i checket! Det er kun kæden af prototyper og `Class.prototype` der har betydning.
-That can lead to interesting consequences when a `prototype` property is changed after the object is created.
+Dette kan føre til interessante konsekvenser når en `prototype` egenskab ændres efter objektet er oprettet.
-Like here:
+Lige som her:
```js run
function Rabbit() {}
let rabbit = new Rabbit();
-// changed the prototype
+// ændret prototypen
Rabbit.prototype = {};
-// ...not a rabbit any more!
+// ...ikke en "Rabbit" mere!
*!*
alert( rabbit instanceof Rabbit ); // false
*/!*
```
-## Bonus: Object.prototype.toString for the type
+## Bonus: Object.prototype.toString for typen
-We already know that plain objects are converted to string as `[object Object]`:
+Vi ved allerede at rene objekter er konverteret til streng som `[object Object]`:
```js run
let obj = {};
alert(obj); // [object Object]
-alert(obj.toString()); // the same
+alert(obj.toString()); // det samme: [object Object]
```
-That's their implementation of `toString`. But there's a hidden feature that makes `toString` actually much more powerful than that. We can use it as an extended `typeof` and an alternative for `instanceof`.
+Det er deres implementering af `toString`. Men der er en skjult feature der faktisk gør `toString` mere kraftfuld end det. Vi kan bruge den som en udvidet `typeof` og et alternativ til `instanceof`.
-Sounds strange? Indeed. Let's demystify.
+Lyder det underligt? Ja, det gør! Men lad os afmystificere det.
-By [specification](https://tc39.github.io/ecma262/#sec-object.prototype.tostring), the built-in `toString` can be extracted from the object and executed in the context of any other value. And its result depends on that value.
+I [specifikationen](https://tc39.github.io/ecma262/#sec-object.prototype.tostring) står der, at den indbyggede `toString` kan trækkes fra objektet og udføres i konteksten af en anden værdi. Og dens resultat afhænger af den værdi.
-- For a number, it will be `[object Number]`
-- For a boolean, it will be `[object Boolean]`
+- For et tal: `[object Number]`
+- For en boolean: `[object Boolean]`
- For `null`: `[object Null]`
- For `undefined`: `[object Undefined]`
- For arrays: `[object Array]`
- ...etc (customizable).
-Let's demonstrate:
+Lad os demonstrere:
```js run
-// copy toString method into a variable for convenience
+// kopier toString til en variabel for nemhedens skyld
let objectToString = Object.prototype.toString;
-// what type is this?
+// hvad type er den?
let arr = [];
alert( objectToString.call(arr) ); // [object *!*Array*/!*]
```
-Here we used [call](mdn:js/function/call) as described in the chapter [](info:call-apply-decorators) to execute the function `objectToString` in the context `this=arr`.
+Her bruger vi [call](mdn:js/function/call) som beskrevet i kapitlet [](info:call-apply-decorators) til at udføre funktionen `objectToString` i konteksten `this=arr`.
-Internally, the `toString` algorithm examines `this` and returns the corresponding result. More examples:
+Internt undersøger `toString` algoritmen `this` og returnerer det tilsvarende resultat. Flere eksempler kunne være:
```js run
let s = Object.prototype.toString;
@@ -186,10 +186,10 @@ let user = {
alert( {}.toString.call(user) ); // [object User]
```
-For most environment-specific objects, there is such a property. Here are some browser specific examples:
+For de fleste miljøspecifikke objekter, er der en sådan egenskab. Her er nogle browser-specifikke eksempler:
```js run
-// toStringTag for the environment-specific object and class:
+// toStringTag til miljøspecifikke objekter og klasser:
alert( window[Symbol.toStringTag]); // Window
alert( XMLHttpRequest.prototype[Symbol.toStringTag] ); // XMLHttpRequest
@@ -197,22 +197,22 @@ alert( {}.toString.call(window) ); // [object Window]
alert( {}.toString.call(new XMLHttpRequest()) ); // [object XMLHttpRequest]
```
-As you can see, the result is exactly `Symbol.toStringTag` (if exists), wrapped into `[object ...]`.
+Som du kan se, er resultatet præcis `Symbol.toStringTag` (hvis den eksisterer), omskrevet til `[object ...]`.
-At the end we have "typeof on steroids" that not only works for primitive data types, but also for built-in objects and even can be customized.
+I enden har vi "typeof on steroids" som ikke kun virker for primitive data typer, men også for indbyggede objekter og endda kan tilpasses.
-We can use `{}.toString.call` instead of `instanceof` for built-in objects when we want to get the type as a string rather than just to check.
+Vi kan bruge `{}.toString.call` i stedet for `instanceof` for indbyggede objekter, når vi vil have typen som en streng i stedet for blot at tjekke.
-## Summary
+## Opsummering
-Let's summarize the type-checking methods that we know:
+Lad os opsummere de type-tjekker, vi kender:
-| | works for | returns |
+| | virker for | returnerer |
|---------------|-------------|---------------|
-| `typeof` | primitives | string |
-| `{}.toString` | primitives, built-in objects, objects with `Symbol.toStringTag` | string |
-| `instanceof` | objects | true/false |
+| `typeof` | primitiver | string |
+| `{}.toString` | primitiver, indbyggede objekter, objekter med `Symbol.toStringTag` | streng |
+| `instanceof` | objekter | true/false |
-As we can see, `{}.toString` is technically a "more advanced" `typeof`.
+Som vi kan se er `{}.toString` teknisk set en "mere avanceret" `typeof`.
-And `instanceof` operator really shines when we are working with a class hierarchy and want to check for the class taking into account inheritance.
+Og `instanceof` operatoren kommer virkelig til sin ret når vi arbejder med en klassehierarki og vil tjekke for klassen med hensyn til arv.
diff --git a/1-js/09-classes/07-mixins/article.md b/1-js/09-classes/07-mixins/article.md
index 526b832ef..d68d32d32 100644
--- a/1-js/09-classes/07-mixins/article.md
+++ b/1-js/09-classes/07-mixins/article.md
@@ -1,22 +1,22 @@
# Mixins
-In JavaScript we can only inherit from a single object. There can be only one `[[Prototype]]` for an object. And a class may extend only one other class.
+I JavaScript kan vi kun nedarve fra et enkelt objekt. Der kan kun være en `[[Prototype]]` for et objekt. Og en klasse kan kun udvide en anden klasse.
-But sometimes that feels limiting. For instance, we have a class `StreetSweeper` and a class `Bicycle`, and want to make their mix: a `StreetSweepingBicycle`.
+Men nogle gange føles det begrænset. For eksempel har vi en klasse `StreetSweeper` og en klasse `Bicycle`, og vi vil lave deres kombination: en `StreetSweepingBicycle`.
-Or we have a class `User` and a class `EventEmitter` that implements event generation, and we'd like to add the functionality of `EventEmitter` to `User`, so that our users can emit events.
+Eller vi har en klasse `User` og en klasse `EventEmitter` som implementerer oprettelse af begivenheder, og vi vil gerne tilføje funktionaliteten af `EventEmitter` til `User`, så vores brugere kan sende begivenheder.
-There's a concept that can help here, called "mixins".
+Der er et koncept der kan hjælpe her, kaldet "mixins".
-As defined in Wikipedia, a [mixin](https://en.wikipedia.org/wiki/Mixin) is a class containing methods that can be used by other classes without a need to inherit from it.
+Fra Wikipedia står der, at [mixin](https://en.wikipedia.org/wiki/Mixin) er en klasse der indeholder metoder, der kan bruges af andre klasser uden at skulle nedarve fra den.
-In other words, a *mixin* provides methods that implement a certain behavior, but we do not use it alone, we use it to add the behavior to other classes.
+Med andre ord, en *mixin* leverer metoder, der implementerer en bestemt adfærd, men vi bruger den ikke alene, vi bruger den til at tilføje adfærd til andre klasser.
-## A mixin example
+## Et mixin eksempel
-The simplest way to implement a mixin in JavaScript is to make an object with useful methods, so that we can easily merge them into a prototype of any class.
+Den nemmeste måde at implementere en mixin i JavaScript er at lave et objekt med et par nyttige metoder, som vi så nemt kan flette dem ind i en prototype af enhver klasse.
-For instance here the mixin `sayHiMixin` is used to add some "speech" for `User`:
+Her er for eksempel en mixin kaldet `sayHiMixin` der kan bruges til at tilføje noget "tale" for klassen `User`:
```js run
*!*
@@ -24,10 +24,10 @@ For instance here the mixin `sayHiMixin` is used to add some "speech" for `User`
*/!*
let sayHiMixin = {
sayHi() {
- alert(`Hello ${this.name}`);
+ alert(`Hej, ${this.name}!`);
},
sayBye() {
- alert(`Bye ${this.name}`);
+ alert(`Farvel, ${this.name}!`);
}
};
@@ -40,14 +40,14 @@ class User {
}
}
-// copy the methods
+// kopier metoderne
Object.assign(User.prototype, sayHiMixin);
-// now User can say hi
-new User("Dude").sayHi(); // Hello Dude!
+// nu kan User sige hej
+new User("Karsten").sayHi(); // Hej, Karsten!
```
-There's no inheritance, but a simple method copying. So `User` may inherit from another class and also include the mixin to "mix-in" the additional methods, like this:
+Der er ingen nedarvning - kun simpel kopiering af metoder. Så `User` kan nedarve fra en anden klasse og også inkludere mixin'en for at "mikse" de yderligere metoder, som dette:
```js
class User extends Person {
@@ -57,9 +57,9 @@ class User extends Person {
Object.assign(User.prototype, sayHiMixin);
```
-Mixins can make use of inheritance inside themselves.
+Mixins kan gøre brug af nedarvning inden i sig selv.
-For instance, here `sayHiMixin` inherits from `sayMixin`:
+For eksempel, her nedarver `sayHiMixin` fra `sayMixin`:
```js run
let sayMixin = {
@@ -69,16 +69,16 @@ let sayMixin = {
};
let sayHiMixin = {
- __proto__: sayMixin, // (or we could use Object.setPrototypeOf to set the prototype here)
+ __proto__: sayMixin, // (eller vi kan bruge Object.setPrototypeOf til at sætte prototype her)
sayHi() {
*!*
- // call parent method
+ // kald forældermetoden
*/!*
- super.say(`Hello ${this.name}`); // (*)
+ super.say(`Hej ${this.name}`); // (*)
},
sayBye() {
- super.say(`Bye ${this.name}`); // (*)
+ super.say(`Farvel ${this.name}`); // (*)
}
};
@@ -88,43 +88,43 @@ class User {
}
}
-// copy the methods
+// kopier metoderne
Object.assign(User.prototype, sayHiMixin);
-// now User can say hi
-new User("Dude").sayHi(); // Hello Dude!
+// nu kan User sige hej
+new User("Karsten").sayHi(); // Hej, Karsten!
```
-Please note that the call to the parent method `super.say()` from `sayHiMixin` (at lines labelled with `(*)`) looks for the method in the prototype of that mixin, not the class.
+Bemærk at kaldet til forældremetoden `super.say()` fra `sayHiMixin` (på linjer mærket med `(*)`) leder efter metoden i prototypen for den mixin, ikke klassen.
-Here's the diagram (see the right part):
+Her er et diagram over det (se den højre del):

-That's because methods `sayHi` and `sayBye` were initially created in `sayHiMixin`. So even though they got copied, their `[[HomeObject]]` internal property references `sayHiMixin`, as shown in the picture above.
+Det er fordi metoderne `sayHi` og `sayBye` indledningsvis blev oprettet i `sayHiMixin`. Så selvom de blev kopieret, henviser deres `[[HomeObject]]` interne egenskab til `sayHiMixin`, som vist i billedet ovenfor.
-As `super` looks for parent methods in `[[HomeObject]].[[Prototype]]`, that means it searches `sayHiMixin.[[Prototype]]`.
+Da `super` leder efter forældremetoder i `[[HomeObject]].[[Prototype]]`, betyder det, at det søger i `sayHiMixin.[[Prototype]]`.
## EventMixin
-Now let's make a mixin for real life.
+Lad os nu oprette en mixin der bruges i virkeligheden.
-An important feature of many browser objects (for instance) is that they can generate events. Events are a great way to "broadcast information" to anyone who wants it. So let's make a mixin that allows us to easily add event-related functions to any class/object.
+En vigtig mulighed for mange browserobjekter (for eksempel) er, at de kan generere hændelser. Hændelser er en fantastisk måde at "kommunisere information" til enhver, der ønsker det. Så lad os lave en mixin, der gør det nemt at tilføje event-relaterede funktioner til enhver klasse/objekt.
-- The mixin will provide a method `.trigger(name, [...data])` to "generate an event" when something important happens to it. The `name` argument is a name of the event, optionally followed by additional arguments with event data.
-- Also the method `.on(name, handler)` that adds `handler` function as the listener to events with the given name. It will be called when an event with the given `name` triggers, and get the arguments from the `.trigger` call.
-- ...And the method `.off(name, handler)` that removes the `handler` listener.
+- Denne mixin vil tilbyde en metode `.trigger(name, [...data])` til at "generere en hændelse" når noget vigtigt sker med den. `name`-argumentet er et navn på hændelsen. Det næste argument er valgfrit og giver mulighed for at sende data med hændelsen.
+- Metoden `.on(name, handler)` tilføjer `handler`-funktionen som lytter til hændelser med det givne navn. Den vil blive kaldt når en hændelse med det givne `name` udløses, og får argumenterne fra kaldet til `.trigger`.
+- ...Endelig er der `.off(name, handler)` som fjerner `handler`-lytteren.
-After adding the mixin, an object `user` will be able to generate an event `"login"` when the visitor logs in. And another object, say, `calendar` may want to listen for such events to load the calendar for the logged-in person.
+Efter at have tilføjet mixin'en, vil et objekt `user` være i stand til at generere en hændelse `"login"` når en besøgende logger ind. Et andet objekt, for eksempel `calendar` kan lytte efter sådan en hændelse for at indlæse kalenderen for den person der er logget ind.
-Or, a `menu` can generate the event `"select"` when a menu item is selected, and other objects may assign handlers to react on that event. And so on.
+Eller en `menu`, kan generere hændelsen `"select"` når et menu-element er valgt, og andre objekter kan tildele funktioner (kaldet handlers) til at reagere på hændelsen. Og så videre.
-Here's the code:
+Her er koden til sådan en mixin:
```js run
let eventMixin = {
/**
- * Subscribe to event, usage:
+ * Abonner på en hændelse, brug:
* menu.on('select', function(item) { ... }
*/
on(eventName, handler) {
@@ -136,7 +136,7 @@ let eventMixin = {
},
/**
- * Cancel the subscription, usage:
+ * Annuller abonnering, brug:
* menu.off('select', handler)
*/
off(eventName, handler) {
@@ -150,59 +150,59 @@ let eventMixin = {
},
/**
- * Generate an event with the given name and data
+ * Opret en hændelse med det givne navn og data
* this.trigger('select', data1, data2);
*/
trigger(eventName, ...args) {
if (!this._eventHandlers?.[eventName]) {
- return; // no handlers for that event name
+ return; // ingen handlers der abonnerer på den hændelse
}
- // call the handlers
+ // kald gemte handlers
this._eventHandlers[eventName].forEach(handler => handler.apply(this, args));
}
};
```
-- `.on(eventName, handler)` -- assigns function `handler` to run when the event with that name occurs. Technically, there's an `_eventHandlers` property that stores an array of handlers for each event name, and it just adds it to the list.
-- `.off(eventName, handler)` -- removes the function from the handlers list.
-- `.trigger(eventName, ...args)` -- generates the event: all handlers from `_eventHandlers[eventName]` are called, with a list of arguments `...args`.
+- `.on(eventName, handler)` -- tildeler funktionen `handler` opgaven at køre når en hændelse med det givne navn opstår. Teknisk set, er der en `_eventHandlers`-egenskab, der gemmer en liste af handlers for hvert hændelsesnavn, og den tilføjer bare funktionen til listen.
+- `.off(eventName, handler)` -- fjerner funktionen fra handler-listen.
+- `.trigger(eventName, ...args)` -- genererer hændelsen: alle handlers fra `_eventHandlers[eventName]` kaldes med en liste af argumenter `...args`.
-Usage:
+Brug af mixin'en er simpel:
```js run
-// Make a class
+// Opret en klasse der bruger mixin'en
class Menu {
choose(value) {
this.trigger("select", value);
}
}
-// Add the mixin with event-related methods
+// Tilføj mixin'en med event-relaterede metoder
Object.assign(Menu.prototype, eventMixin);
let menu = new Menu();
-// add a handler, to be called on selection:
+// tilføj en handler, der skal kaldes ved valg:
*!*
-menu.on("select", value => alert(`Value selected: ${value}`));
+menu.on("select", value => alert(`Valgte værdi: ${value}`));
*/!*
-// triggers the event => the handler above runs and shows:
-// Value selected: 123
+// trigger en hændelse => handleren ovenfor kører og viser:
+// Valgte værdi: 123
menu.choose("123");
```
-Now, if we'd like any code to react to a menu selection, we can listen for it with `menu.on(...)`.
+Nu, hvis vi vil have kode til at reagere på et menuvalg, kan vi lytte efter det med `menu.on(...)`.
-And `eventMixin` mixin makes it easy to add such behavior to as many classes as we'd like, without interfering with the inheritance chain.
+Derudover gør `eventMixin` mixin nemt at tilføje sådan adfærd til så mange klasser som vi ønsker, uden at påvirke arvekæden.
-## Summary
+## Opsummering
-*Mixin* -- is a generic object-oriented programming term: a class that contains methods for other classes.
+*Mixin* -- er en generisk objektorienteret programmeringsterm: en klasse, der indeholder metoder for andre klasser.
-Some other languages allow multiple inheritance. JavaScript does not support multiple inheritance, but mixins can be implemented by copying methods into prototype.
+Nogle andre sprog tillader nedarvning fra flere klasser. Det gør JavaScript ikke, men mixins kan implementere noget der minder om det ved at kopiere metoder ind i en prototype.
-We can use mixins as a way to augment a class by adding multiple behaviors, like event-handling as we have seen above.
+Vi kan bruge mixins som en måde at udvide en klasses adfærd, som f. eks. event-handling som vi har set ovenfor.
-Mixins may become a point of conflict if they accidentally overwrite existing class methods. So generally one should think well about the naming methods of a mixin, to minimize the probability of that happening.
+Mixins kan blive et problem, hvis de tilfældigt overskriver eksisterende klassemetoder. Så det er en god idé at tænke godt over navngivningen af metoderne i en mixin, for at minimere sandsynligheden for, at det sker.
diff --git a/1-js/09-classes/07-mixins/head.html b/1-js/09-classes/07-mixins/head.html
index 20e3a6354..469a06571 100644
--- a/1-js/09-classes/07-mixins/head.html
+++ b/1-js/09-classes/07-mixins/head.html
@@ -1,43 +1,42 @@
diff --git a/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/solution.md b/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/solution.md
index ec0dabc9a..20f367344 100644
--- a/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/solution.md
+++ b/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/solution.md
@@ -1,47 +1,47 @@
-The difference becomes obvious when we look at the code inside a function.
+Forskellen bliver tydelig, når vi kigger på koden inde i en funktion.
-The behavior is different if there's a "jump out" of `try...catch`.
+Det er forskelligt, hvis der er et "spring ud" af `try...catch`.
-For instance, when there's a `return` inside `try...catch`. The `finally` clause works in case of *any* exit from `try...catch`, even via the `return` statement: right after `try...catch` is done, but before the calling code gets the control.
+For eksempel, når der er en `return` inde i `try...catch`. `finally`-klausulen virker i tilfældet af *hvilken som helst* afslutning fra `try...catch`, selv via `return`-sætningen: lige efter `try...catch` er færdig, men før den kaldende kode får kontrollen.
```js run
function f() {
try {
alert('start');
*!*
- return "result";
+ return "resultat";
*/!*
} catch (err) {
/// ...
} finally {
- alert('cleanup!');
+ alert('oprydning!');
}
}
-f(); // cleanup!
+f(); // oprydning!
```
-...Or when there's a `throw`, like here:
+...eller hvis der er en `throw`, som her:
```js run
function f() {
try {
alert('start');
- throw new Error("an error");
+ throw new Error("en fejl");
} catch (err) {
// ...
- if("can't handle the error") {
+ if("kan ikke håndtere fejlen") {
*!*
throw err;
*/!*
}
} finally {
- alert('cleanup!')
+ alert('oprydning!')
}
}
-f(); // cleanup!
+f(); // oprydning!
```
-It's `finally` that guarantees the cleanup here. If we just put the code at the end of `f`, it wouldn't run in these situations.
+Det er `finally` der garanterer oprydningen her. Hvis vi bare sætter koden ved slutningen af `f`, ville den ikke køre i disse situationer.
diff --git a/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/task.md b/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/task.md
index b6dc81326..c5663cbac 100644
--- a/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/task.md
+++ b/1-js/10-error-handling/1-try-catch/1-finally-or-code-after/task.md
@@ -4,35 +4,35 @@ importance: 5
# Finally or just the code?
-Compare the two code fragments.
+Sammenlign disse to kodefragmenter.
-1. The first one uses `finally` to execute the code after `try...catch`:
+1. Den første bruger `finally` til at køre koden efter `try...catch`:
```js
try {
- work work
+ arbejd' arbejd'
} catch (err) {
- handle errors
+ håndter fejl
} finally {
*!*
- cleanup the working space
+ ryd op på arbejdspladsen
*/!*
}
```
-2. The second fragment puts the cleaning right after `try...catch`:
+2. Den anden placerer oprydningen lige efter `try...catch`:
```js
try {
- work work
+ arbejd' arbejd'
} catch (err) {
- handle errors
+ håndter fejl
}
*!*
- cleanup the working space
+ ryd op på arbejdspladsen
*/!*
```
-We definitely need the cleanup after the work, doesn't matter if there was an error or not.
+Vi skal selvfølgelig have oprydningen efter arbejdet, uanset om der var en fejl eller ej.
-Is there an advantage here in using `finally` or both code fragments are equal? If there is such an advantage, then give an example when it matters.
+Er der en fordel i at bruge `finally` eller er de to kodefragmenter ens? Hvis der er en sådan fordel, så giv et eksempel på, når det betyder noget.
diff --git a/1-js/10-error-handling/1-try-catch/article.md b/1-js/10-error-handling/1-try-catch/article.md
index cad2e1a3e..a8bf2b7ba 100644
--- a/1-js/10-error-handling/1-try-catch/article.md
+++ b/1-js/10-error-handling/1-try-catch/article.md
@@ -1,98 +1,98 @@
-# Error handling, "try...catch"
+# Håndtering af fejl, "try...catch"
-No matter how great we are at programming, sometimes our scripts have errors. They may occur because of our mistakes, an unexpected user input, an erroneous server response, and for a thousand other reasons.
+Uanset hvor gode vi er til programmering, så har vores scripts periodisk fejl. De kan opstå på grund af vores fejl, et uventet brugerinput, et fejlbehæftet server svar, og for tusind andre grunde.
-Usually, a script "dies" (immediately stops) in case of an error, printing it to console.
+Normalt dør et script (stoppes øjeblikkeligt) når en fejl opstår, og fejlen udskrives til konsollen.
-But there's a syntax construct `try...catch` that allows us to "catch" errors so the script can, instead of dying, do something more reasonable.
+Men der er en konstruktion `try...catch` som tillader os at "fange" fejl, så scriptet kan gøre noget mere fornuftigt end at dø.
-## The "try...catch" syntax
+## Syntaksen "try...catch"
-The `try...catch` construct has two main blocks: `try`, and then `catch`:
+Konstruktionen `try...catch` har to hovedblokke: `try`, og derefter `catch`:
```js
try {
- // code...
+ // kode...
} catch (err) {
- // error handling
+ // fejlhåndtering
}
```
-It works like this:
+Det virker sådan:
-1. First, the code in `try {...}` is executed.
-2. If there were no errors, then `catch (err)` is ignored: the execution reaches the end of `try` and goes on, skipping `catch`.
-3. If an error occurs, then the `try` execution is stopped, and control flows to the beginning of `catch (err)`. The `err` variable (we can use any name for it) will contain an error object with details about what happened.
+1. Først vil koden i `try {...}` blive kørt.
+2. Hvis der ikke er nogen fejl, så ignoreres `catch (err)`: eksekveringen når til slutningen af `try` og går videre, springer over `catch`.
+3. Hvis en fejl opstår, så stoppes `try`-eksekveringen, og kontrol flyttes til begyndelsen af `catch (err)`. Den `err`-variabel (vi kan bruge et hvilket som helst navn) vil indeholde et fejlobjekt med detaljer om, hvad der skete.

-So, an error inside the `try {...}` block does not kill the script -- we have a chance to handle it in `catch`.
+Så, hvis der sker en fejl inde i `try {...}` blokken, så dør scriptet ikke -- vi har en chance til at håndtere den i `catch`.
-Let's look at some examples.
+Lad os se på et par eksempler.
-- An errorless example: shows `alert` `(1)` and `(2)`:
+- Et eksempel uden fejl: viser `alert` `(1)` og `(2)`:
```js run
try {
- alert('Start of try runs'); // *!*(1) <--*/!*
+ alert('Start på "try runs"'); // *!*(1) <--*/!*
- // ...no errors here
+ // ...ingen fejl her
- alert('End of try runs'); // *!*(2) <--*/!*
+ alert('Slut på "try runs"'); // *!*(2) <--*/!*
} catch (err) {
- alert('Catch is ignored, because there are no errors'); // (3)
+ alert('Catch ignoreres fordi der ikke var fejl'); // (3)
}
```
-- An example with an error: shows `(1)` and `(3)`:
+- Et eksempel med en fejl: viser `(1)` og `(3)`:
```js run
try {
- alert('Start of try runs'); // *!*(1) <--*/!*
+ alert('Start på "try runs"'); // *!*(1) <--*/!*
*!*
- lalala; // error, variable is not defined!
+ lalala; // fejl, variable is not defined!
*/!*
- alert('End of try (never reached)'); // (2)
+ alert('Slut på "try runs"'); // (2)
} catch (err) {
- alert(`Error has occurred!`); // *!*(3) <--*/!*
+ alert(`Der skete en fejl!`); // *!*(3) <--*/!*
}
```
-````warn header="`try...catch` only works for runtime errors"
-For `try...catch` to work, the code must be runnable. In other words, it should be valid JavaScript.
+````warn header="`try...catch` virker kun for runtime errors"
+For at `try...catch` skal virke skal koden kunne køre. Med anre ord skal det være gyldig (valid) JavaScript.
-It won't work if the code is syntactically wrong, for instance it has unmatched curly braces:
+Den virker ikke hvis syntaksen er forkert. For eksempel hvis der er rod med parenteser:
```js run
try {
{{{{{{{{{{{{
} catch (err) {
- alert("The engine can't understand this code, it's invalid");
+ alert("Motoren forstår ikke denne kode, den er ugyldig");
}
```
-The JavaScript engine first reads the code, and then runs it. The errors that occur on the reading phase are called "parse-time" errors and are unrecoverable (from inside that code). That's because the engine can't understand the code.
+JavaScript-motoren læser koden først, og derefter kører den. De fejl, der opstår under læsningen, kaldes "parse-time" fejl og er unrecoverable (fra inde i koden). Det er fordi motoren ikke kan forstå koden.
-So, `try...catch` can only handle errors that occur in valid code. Such errors are called "runtime errors" or, sometimes, "exceptions".
-````
+Så, `try...catch` kan kun håndtere fejl, der opstår i gyldig kode. Sådanne fejl kaldes "runtime errors" eller, nogle gange, "exceptions".
+```
-````warn header="`try...catch` works synchronously"
-If an exception happens in "scheduled" code, like in `setTimeout`, then `try...catch` won't catch it:
+````warn header="`try...catch` virker synkront"
+Hvis en exception opstår i "planlagt" kode, som i `setTimeout`, så vil `try...catch` ikke fange den:
```js run
try {
@@ -100,112 +100,112 @@ try {
noSuchVariable; // script will die here
}, 1000);
} catch (err) {
- alert( "won't work" );
+ alert( "det her virker ikke" );
}
```
-That's because the function itself is executed later, when the engine has already left the `try...catch` construct.
+Det er fordi at selve funktionen først afvikles senere - det har motoren allerede forladt `try...catch` konstruktionen.
-To catch an exception inside a scheduled function, `try...catch` must be inside that function:
+For at fange en exception inde i en planlagt funktion, skal `try...catch` være inde i selve funktionen:
```js run
setTimeout(function() {
try {
- noSuchVariable; // try...catch handles the error!
+ noSuchVariable; // try...catch håndterer fejlen!
} catch {
- alert( "error is caught here!" );
+ alert( "fejlen fanges her!" );
}
}, 1000);
```
````
-## Error object
+## Error objekt
-When an error occurs, JavaScript generates an object containing the details about it. The object is then passed as an argument to `catch`:
+Når der opstår en fejl, genererer JavaScript et objekt, der indeholder detaljerne om fejlen. Objektet sendes derefter som et argument til `catch`:
```js
try {
// ...
-} catch (err) { // <-- the "error object", could use another word instead of err
+} catch (err) { // <-- her er "error objektet", du kan sagtens bruge et andet navn istedet for err
// ...
}
```
-For all built-in errors, the error object has two main properties:
+For alle indbyggede fejl har error objektet to hovedegenskaber:
`name`
-: Error name. For instance, for an undefined variable that's `"ReferenceError"`.
+: Navnet på fejlen. Hvis det for eksempel er en ikke-defineret variabel, så indeholder den `"ReferenceError"`.
`message`
-: Textual message about error details.
+: En tekst der beskriver fejlen.
-There are other non-standard properties available in most environments. One of most widely used and supported is:
+Der er andre ikke-standard egenskaber tilgængelige i de fleste miljøer. En af de mest brugte og understøttede er:
`stack`
-: Current call stack: a string with information about the sequence of nested calls that led to the error. Used for debugging purposes.
+: Aktuel kaldestak: en streng med information om sekvensen af indlejrede kald, der ledte til fejlen. Bruges til fejlfinding.
-For instance:
+For eksempel:
```js run untrusted
try {
*!*
- lalala; // error, variable is not defined!
+ lalala; // fejl, variablen er ikke defineret!
*/!*
} catch (err) {
alert(err.name); // ReferenceError
alert(err.message); // lalala is not defined
alert(err.stack); // ReferenceError: lalala is not defined at (...call stack)
- // Can also show an error as a whole
- // The error is converted to string as "name: message"
+ // Kan også vise en fejl som et samlet output
+ // Fejlen konverteres til en streng som "name: message"
alert(err); // ReferenceError: lalala is not defined
}
```
-## Optional "catch" binding
+## Frivillig "catch" binding
[recent browser=new]
-If we don't need error details, `catch` may omit it:
+Hvis vi ikke behøver detaljer om fejlen, kan `catch` udelade den:
```js
try {
// ...
-} catch { // <-- without (err)
+} catch { // <-- uden (err)
// ...
}
```
-## Using "try...catch"
+## Brug af "try...catch"
-Let's explore a real-life use case of `try...catch`.
+Lad os udforske brugsscenarier for `try...catch`.
-As we already know, JavaScript supports the [JSON.parse(str)](mdn:js/JSON/parse) method to read JSON-encoded values.
+Som vi allerede ved så understøtter JavaScript metoden [JSON.parse(str)](mdn:js/JSON/parse) til at læse JSON værdier.
-Usually it's used to decode data received over the network, from the server or another source.
+Normalt bruges den til at afkode data der er modtaget over netværket, fra serveren eller anden kilde.
-We receive it and call `JSON.parse` like this:
+Vi modtager det og kalder `JSON.parse` sådan her:
```js run
let json = '{"name":"John", "age": 30}'; // data from the server
*!*
-let user = JSON.parse(json); // convert the text representation to JS object
+let user = JSON.parse(json); // konverterer tekstrepræsentation til JS-objekt
*/!*
-// now user is an object with properties from the string
+// nu er user et objekt med egenskaber fra strengen
alert( user.name ); // John
alert( user.age ); // 30
```
-You can find more detailed information about JSON in the chapter.
+Du kan finde mere detaljeret information om JSON i kapitlet .
-**If `json` is malformed, `JSON.parse` generates an error, so the script "dies".**
+**Hvis `json` indeholder fejl vil `JSON.parse` generere en fejl, så scriptet "dør".**
-Should we be satisfied with that? Of course not!
+Skal vi stille os tilfreds med det? Nej, selvfølgelig ikke!
-This way, if something's wrong with the data, the visitor will never know that (unless they open the developer console). And people really don't like when something "just dies" without any error message.
+På denne måde, hvis der er noget galt med data, vil besøgende aldrig vide det (medmindre de åbner konsollen). Og folk kan ikke li', når noget "bare dør" uden nogen fejlbesked.
-Let's use `try...catch` to handle the error:
+Lad os bruge `try...catch` til at håndtere fejlen:
```js run
let json = "{ bad json }";
@@ -213,74 +213,74 @@ let json = "{ bad json }";
try {
*!*
- let user = JSON.parse(json); // <-- when an error occurs...
+ let user = JSON.parse(json); // <-- når en fejl opstår...
*/!*
- alert( user.name ); // doesn't work
+ alert( user.name ); // virker ikke
} catch (err) {
*!*
- // ...the execution jumps here
- alert( "Our apologies, the data has errors, we'll try to request it one more time." );
+ // ...hopper afviklingen her til
+ alert( "Desværre indeholder vores data fejl, vi vil forsøge at anmode om den en gang til." );
alert( err.name );
alert( err.message );
*/!*
}
```
-Here we use the `catch` block only to show the message, but we can do much more: send a new network request, suggest an alternative to the visitor, send information about the error to a logging facility, ... . All much better than just dying.
+Her bruger vi kun `catch` blokken til at vise en besked, men vi kan gøre meget andet: sende et nyt netværkskald, foreslå et alternativ til besøgende, send information om fejlen til en log, ... alle muligheder der er meget bedre end bare at dø.
-## Throwing our own errors
+## Kaste vores egne fejl
-What if `json` is syntactically correct, but doesn't have a required `name` property?
+Hvad hvis `json` er syntactisk korrekt, men ikke har en påkrævet `name` egenskab?
-Like this:
+Som dette:
```js run
-let json = '{ "age": 30 }'; // incomplete data
+let json = '{ "age": 30 }'; // ufuldstændige data
try {
- let user = JSON.parse(json); // <-- no errors
+ let user = JSON.parse(json); // <-- ingen fejl
*!*
- alert( user.name ); // no name!
+ alert( user.name ); // intet navn!
*/!*
} catch (err) {
- alert( "doesn't execute" );
+ alert( "afvikles ikke" );
}
```
-Here `JSON.parse` runs normally, but the absence of `name` is actually an error for us.
+Her kører `JSON.parse` normalt, men fraværet af `name` er faktisk en fejl for os.
-To unify error handling, we'll use the `throw` operator.
+For at ensrette fejlhåndteringen, vil vi bruge `throw` operatoren.
### "Throw" operator
-The `throw` operator generates an error.
+Operatoren `throw` genererer en fejl.
-The syntax is:
+Syntaksen er:
```js
throw
```
-Technically, we can use anything as an error object. That may be even a primitive, like a number or a string, but it's better to use objects, preferably with `name` and `message` properties (to stay somewhat compatible with built-in errors).
+Teknisk set kan vi kaste hvad som helst som et error objekt. Det kan endda være en primitiv, som et tal eller en streng, men det er bedre at bruge objekter, især med `name` og `message` egenskaber (for at forblive nogenlunde kompatibel med de indbyggede fejl).
-JavaScript has many built-in constructors for standard errors: `Error`, `SyntaxError`, `ReferenceError`, `TypeError` and others. We can use them to create error objects as well.
+JavaScript har mange indbyggede konstruktører for standardfejl: `Error`, `SyntaxError`, `ReferenceError`, `TypeError` og andre. Vi kan bruge dem til at oprette fejlobjekter.
-Their syntax is:
+Deres syntaks er:
```js
let error = new Error(message);
-// or
+// eller
let error = new SyntaxError(message);
let error = new ReferenceError(message);
// ...
```
-For built-in errors (not for any objects, just for errors), the `name` property is exactly the name of the constructor. And `message` is taken from the argument.
+For indbyggede fejl (ikke for objekter generelt, kun for fejl) er `name` egenskaben præcis det samme som navnet på konstruktøren, og `message` er taget fra argumentet.
-For instance:
+For eksempel:
```js run
let error = new Error("Things happen o_O");
@@ -289,7 +289,7 @@ alert(error.name); // Error
alert(error.message); // Things happen o_O
```
-Let's see what kind of error `JSON.parse` generates:
+Lad os se hvilken fejl `JSON.parse` genererer, når den ikke kan læse data:
```js run
try {
@@ -302,14 +302,14 @@ try {
}
```
-As we can see, that's a `SyntaxError`.
+Som vi kan se er det en `SyntaxError`.
-And in our case, the absence of `name` is an error, as users must have a `name`.
+Og i vores tilfælde er fraværet af `name` en fejl, da brugere skal have et `name`.
-So let's throw it:
+Så lad os kaste den fejl, og håndtere den i `catch`:
```js run
-let json = '{ "age": 30 }'; // incomplete data
+let json = '{ "age": 30 }'; // ufuldstændige data
try {
@@ -317,55 +317,55 @@ try {
if (!user.name) {
*!*
- throw new SyntaxError("Incomplete data: no name"); // (*)
+ throw new SyntaxError("Ufuldstændige data: name mangler"); // (*)
*/!*
}
alert( user.name );
} catch (err) {
- alert( "JSON Error: " + err.message ); // JSON Error: Incomplete data: no name
+ alert( "JSON Error: " + err.message ); // JSON Error: Ufuldstændige data: name mangler
}
```
-In the line `(*)`, the `throw` operator generates a `SyntaxError` with the given `message`, the same way as JavaScript would generate it itself. The execution of `try` immediately stops and the control flow jumps into `catch`.
+I linjen med `(*)`, genererer `throw` operatoren en `SyntaxError` med den angivne `message`, på samme måde som JavaScript ville generere det selv. Afviklingen af `try` stopper med det samme og kontrollen af flower overgår til `catch`.
-Now `catch` became a single place for all error handling: both for `JSON.parse` and other cases.
+Nu bliver `catch` det eneste sted for al fejlhåndtering: både for `JSON.parse` og for andre scenarier.
## Rethrowing
-In the example above we use `try...catch` to handle incorrect data. But is it possible that *another unexpected error* occurs within the `try {...}` block? Like a programming error (variable is not defined) or something else, not just this "incorrect data" thing.
+I eksemplet ovenfor bruger vi `try...catch` til at håndtere forkert data i JSON filen. Men er det muligt at *en anden uventet fejl* opstår inden for `try {...}` blokken? Som en programmeringsfejl (variabel er ikke defineret) eller noget andet, ikke bare denne "forkerte data" ting.
-For example:
+For eksempel:
```js run
-let json = '{ "age": 30 }'; // incomplete data
+let json = '{ "age": 30 }'; // ufuldstændige data
try {
- user = JSON.parse(json); // <-- forgot to put "let" before user
+ user = JSON.parse(json); // <-- glemte at putte "let" foran user
// ...
} catch (err) {
- alert("JSON Error: " + err); // JSON Error: ReferenceError: user is not defined
- // (no JSON Error actually)
+ alert("JSON Fejl: " + err); // JSON Fejl: ReferenceError: user is not defined
+ // (faktisk ikke en JSON fejl)
}
```
-Of course, everything's possible! Programmers do make mistakes. Even in open-source utilities used by millions for decades -- suddenly a bug may be discovered that leads to terrible hacks.
+Selvfølgelig, alt er muligt! Programmører laver fejl. Selv i open-source værktøjer der er brugt af millioner i årtier -- pludselig kan en fejl blive opdaget, der fører til frygtelige hacks.
-In our case, `try...catch` is placed to catch "incorrect data" errors. But by its nature, `catch` gets *all* errors from `try`. Here it gets an unexpected error, but still shows the same `"JSON Error"` message. That's wrong and also makes the code more difficult to debug.
+I vores tilfælde, `try...catch` er placeret for at fange "forkerte data" fejl. Men selve konstrulktionen dikterer at `catch` får *alle* fejl fra `try`. Her får det en uventet fejl, men viser stadig den samme `"JSON Error"` besked. Det er forkert og gør også koden sværere at debugge.
-To avoid such problems, we can employ the "rethrowing" technique. The rule is simple:
+For at undgå sådanne problemer, kan vi bruge "rethrowing" teknikken. Reglen er simpel:
-**Catch should only process errors that it knows and "rethrow" all others.**
+**Catch skal kun behandle fejl, den kender, og "rethrow" alle andre.**
-The "rethrowing" technique can be explained in more detail as:
+Teknikken "rethrowing" kan forklares lidt mere detaljeret som:
-1. Catch gets all errors.
-2. In the `catch (err) {...}` block we analyze the error object `err`.
-3. If we don't know how to handle it, we do `throw err`.
+1. Opfang alle fejl.
+2. I blokken `catch (err) {...}` analyserer vi error objektet.
+3. Hvis vi ikke ved, hvordan vi skal håndtere den, kaster vi den med `throw err`.
-Usually, we can check the error type using the `instanceof` operator:
+Normalt kan vi tjekke fejltypen ved hjælp af `instanceof` operatoren:
```js run
try {
@@ -374,27 +374,27 @@ try {
*!*
if (err instanceof ReferenceError) {
*/!*
- alert('ReferenceError'); // "ReferenceError" for accessing an undefined variable
+ alert('ReferenceError'); // "ReferenceError" for at tilgå en variabel der er undefineret
}
}
```
-We can also get the error class name from `err.name` property. All native errors have it. Another option is to read `err.constructor.name`.
+Vi kan også få fejlens navn fra `err.name` egenskaben. Alle indbyggede fejl har den. En anden option er at læse `err.constructor.name`.
-In the code below, we use rethrowing so that `catch` only handles `SyntaxError`:
+I koden nedenfor, vi bruger rethrowing så `catch` kun håndterer `SyntaxError`:
```js run
-let json = '{ "age": 30 }'; // incomplete data
+let json = '{ "age": 30 }'; // ufuldstændige data
try {
let user = JSON.parse(json);
if (!user.name) {
- throw new SyntaxError("Incomplete data: no name");
+ throw new SyntaxError("Ufuldstændige data: name mangler");
}
*!*
- blabla(); // unexpected error
+ blabla(); // uventet fejl
*/!*
alert( user.name );
@@ -403,7 +403,7 @@ try {
*!*
if (err instanceof SyntaxError) {
- alert( "JSON Error: " + err.message );
+ alert( "JSON fejl: " + err.message );
} else {
throw err; // rethrow (*)
}
@@ -412,11 +412,11 @@ try {
}
```
-The error throwing on line `(*)` from inside `catch` block "falls out" of `try...catch` and can be either caught by an outer `try...catch` construct (if it exists), or it kills the script.
+Fejlkastningen på linjen med `(*)` inde i `catch` blokken "falder ud" af `try...catch` og kan enten blive fanget af en ydre `try...catch` construct (hvis den eksisterer), eller også dør scriptet.
-So the `catch` block actually handles only errors that it knows how to deal with and "skips" all others.
+Så `catch` blokken håndterer faktisk kun fejl, den ved hvordan den skal håndtere, og "dropper" alle andre.
-The example below demonstrates how such errors can be caught by one more level of `try...catch`:
+Eksemplet nedenfor viser, hvordan sådanne fejl kan blive fanget af et ekstra niveau af `try...catch`:
```js run
function readData() {
@@ -425,13 +425,13 @@ function readData() {
try {
// ...
*!*
- blabla(); // error!
+ blabla(); // fejl!
*/!*
} catch (err) {
// ...
if (!(err instanceof SyntaxError)) {
*!*
- throw err; // rethrow (don't know how to deal with it)
+ throw err; // rethrow (ved ikke hvordan man skal håndtere det)
*/!*
}
}
@@ -441,42 +441,42 @@ try {
readData();
} catch (err) {
*!*
- alert( "External catch got: " + err ); // caught it!
+ alert( "Ydre catch modtog: " + err ); // fangede den!
*/!*
}
```
-Here `readData` only knows how to handle `SyntaxError`, while the outer `try...catch` knows how to handle everything.
+Her ved `readData` kun hvordan den skal håndtere `SyntaxError`, mens den ydre `try...catch` ved hvordan den skal håndtere alt.
## try...catch...finally
-Wait, that's not all.
+vent, der er mere endnu.
-The `try...catch` construct may have one more code clause: `finally`.
+Konstruktionen `try...catch` har en såkaldt klausul mere, nemlig `finally`.
-If it exists, it runs in all cases:
+Hvis den eksisterer, kører den i alle tilfælde:
-- after `try`, if there were no errors,
-- after `catch`, if there were errors.
+- efter `try`, hvis der ikke var nogen fejl,
+- efter `catch`, hvis der var fejl.
-The extended syntax looks like this:
+Den udvidede syntaks ser sådan ud:
```js
*!*try*/!* {
- ... try to execute the code ...
+ ... prøv at afvikle noget kode ...
} *!*catch*/!* (err) {
- ... handle errors ...
+ ... håndter fejl ...
} *!*finally*/!* {
- ... execute always ...
+ ... kører altid til sidst ...
}
```
-Try running this code:
+Prøv at køre denne kode for at se, hvordan det fungerer:
```js run
try {
alert( 'try' );
- if (confirm('Make an error?')) BAD_CODE();
+ if (confirm('Skal der laves en fejl?')) BAD_CODE();
} catch (err) {
alert( 'catch' );
} finally {
@@ -484,27 +484,27 @@ try {
}
```
-The code has two ways of execution:
+Koden har to måder at blive afviklet på:
-1. If you answer "Yes" to "Make an error?", then `try -> catch -> finally`.
-2. If you say "No", then `try -> finally`.
+1. Hvis du svarer "Ja" til "Skal der laves en fejl?", så `try -> catch -> finally`.
+2. Hvis du svarer "Nej", så `try -> finally`.
-The `finally` clause is often used when we start doing something and want to finalize it in any case of outcome.
+Klausulen `finally` bruges ofte, når vi starter noget og vil have det afsluttet uanset resultatet.
-For instance, we want to measure the time that a Fibonacci numbers function `fib(n)` takes. Naturally, we can start measuring before it runs and finish afterwards. But what if there's an error during the function call? In particular, the implementation of `fib(n)` in the code below returns an error for negative or non-integer numbers.
+For eksempel, vi vil måle tiden, det tager at køre en Fibonacci tal funktion `fib(n)`. Naturligvis kan vi starte måling før den kører og afslutte efterfølgende. Men hvad hvis der er en fejl under funktionskaldet? Især implementationen af `fib(n)` i koden nedenfor returnerer en fejl for negative eller ikke-heltalstal.
-The `finally` clause is a great place to finish the measurements no matter what.
+`finally` klausulen er et godt sted at afslutte målingerne uanset hvad.
-Here `finally` guarantees that the time will be measured correctly in both situations -- in case of a successful execution of `fib` and in case of an error in it:
+Her garanterer `finally` at tiden vil blive målt korrekt i begge situationer -- i tilfælde af en succesfuld udførelse af `fib` og i tilfælde af en fejl i den:
```js run
-let num = +prompt("Enter a positive integer number?", 35)
+let num = +prompt("Skriv et positivt heltal?", 35)
let diff, result;
function fib(n) {
if (n < 0 || Math.trunc(n) != n) {
- throw new Error("Must not be negative, and also an integer.");
+ throw new Error("Tallet må ikke være negativt, og det skal være et heltal.");
}
return n <= 1 ? n : fib(n - 1) + fib(n - 2);
}
@@ -521,26 +521,26 @@ try {
}
*/!*
-alert(result || "error occurred");
+alert(result || "der skete en fejl");
-alert( `execution took ${diff}ms` );
+alert( `udførelsen tog ${diff}ms` );
```
-You can check by running the code with entering `35` into `prompt` -- it executes normally, `finally` after `try`. And then enter `-1` -- there will be an immediate error, and the execution will take `0ms`. Both measurements are done correctly.
+Du kan nu køre koden med at indtaste `35` i `prompt` -- den kører normalt, `finally` efter `try`. Prøv bagefter at indtaste `-1` -- der vil umiddelbart være en fejl, og udførelsen vil tage `0ms`. Begge målinger er udført korrekt.
-In other words, the function may finish with `return` or `throw`, that doesn't matter. The `finally` clause executes in both cases.
+Med andre ord, funktionen kan slutte med `return` eller `throw`, det spiller ingen rolle. Klausulen `finally` udføres i begge tilfælde.
-```smart header="Variables are local inside `try...catch...finally`"
-Please note that `result` and `diff` variables in the code above are declared *before* `try...catch`.
+```smart header="Variable er lokale inde i `try...catch...finally`"
+Bemærk at `result` og `diff` variablene i koden ovenfor er deklareret *før* `try...catch`.
-Otherwise, if we declared `let` in `try` block, it would only be visible inside of it.
+Ellers, hvis vi deklarerede `let` i `try` blokken, ville den kun være synlig inden for den.
```
-````smart header="`finally` and `return`"
-The `finally` clause works for *any* exit from `try...catch`. That includes an explicit `return`.
+````smart header="`finally` og `return`"
+Klausulen `finally` virker for *alle* udgange fra `try...catch`. Det indbefatter også en eksplicit `return`.
-In the example below, there's a `return` in `try`. In this case, `finally` is executed just before the control returns to the outer code.
+I eksemplet nedenfor, er der en `return` i `try`. I dette tilfælde, udføres `finally` lige før kontrol returnerer til den ydre kode.
```js run
function func() {
@@ -559,40 +559,40 @@ function func() {
}
}
-alert( func() ); // first works alert from finally, and then this one
+alert( func() ); // først kommer alert fra finally, og derefter kommer denne der kalder func()
```
````
````smart header="`try...finally`"
-The `try...finally` construct, without `catch` clause, is also useful. We apply it when we don't want to handle errors here (let them fall through), but want to be sure that processes that we started are finalized.
+Konstruktionen `try...finally` uden klausulen `catch` kan også være brugbar. Den bruger vi, hvis vi ikke vil håndtere fejl her (lad dem falde gennem), men vil være sikker på, at processer, vi har startet, bliver afsluttet.
```js
function func() {
- // start doing something that needs completion (like measurements)
+ // start noget der skal afsluttes (som målinger, eller en databaseforbindelse, eller noget andet)
try {
// ...
} finally {
- // complete that thing even if all dies
+ // førdiggør eller ryd op lige meget om det fejler eller ej
}
}
```
-In the code above, an error inside `try` always falls out, because there's no `catch`. But `finally` works before the execution flow leaves the function.
+I koden ovenfor vil en fejl inde `try` altid falde ud, fordi der ikke er en `catch`. Men `finally` virker før afviklingsflowet forlader funktionen.
````
## Global catch
-```warn header="Environment-specific"
-The information from this section is not a part of the core JavaScript.
+```warn header="Miljøspecifikt"
+Informationen i denne sektion er ikke en del af selve JavaScript sproget.
```
-Let's imagine we've got a fatal error outside of `try...catch`, and the script died. Like a programming error or some other terrible thing.
+Lad os forestille os, at vi får en fatal fejl uden for `try...catch`, og scriptet dør. Som en programmeringsfejl eller noget andet skrækkeligt.
-Is there a way to react on such occurrences? We may want to log the error, show something to the user (normally they don't see error messages), etc.
+Er der en måde at reagere på sådanne tilfælde? Vi vil måske logge fejlen, vise noget til brugeren (normalt ser de ikke fejlbeskeder), etc.
-There is none in the specification, but environments usually provide it, because it's really useful. For instance, Node.js has [`process.on("uncaughtException")`](https://nodejs.org/api/process.html#process_event_uncaughtexception) for that. And in the browser we can assign a function to the special [window.onerror](mdn:api/GlobalEventHandlers/onerror) property, that will run in case of an uncaught error.
+Der er ingen i specifikationen, men miljøer ofte leverer det, fordi det er virkelig nyttigt. For eksempel har Node.js [`process.on("uncaughtException")`](https://nodejs.org/api/process.html#process_event_uncaughtexception) for det. Og i browseren kan vi tildele en funktion til den specielle [window.onerror](mdn:api/GlobalEventHandlers/onerror) egenskab, som vil køre i tilfælde af en ikke-fanget fejl.
-The syntax:
+Syntaksen er:
```js
window.onerror = function(message, url, line, col, error) {
@@ -601,18 +601,18 @@ window.onerror = function(message, url, line, col, error) {
```
`message`
-: Error message.
+: Fejlmeddelelsen.
`url`
-: URL of the script where error happened.
+: URL for det script hvor fejlen opstod.
`line`, `col`
-: Line and column numbers where error happened.
+: Linje og kolonne numre hvor fejlen opstod.
`error`
-: Error object.
+: Error objekt.
-For instance:
+For eksempel, denne kode har en fejl, og den vil blive fanget af `window.onerror`:
```html run untrusted refresh height=1
```
-The role of the global handler `window.onerror` is usually not to recover the script execution -- that's probably impossible in case of programming errors, but to send the error message to developers.
-
-There are also web-services that provide error-logging for such cases, like or .
+Rollen for den globale håndtering med `window.onerror` er normalt ikke for at genskabe scripteksekveringen -- det er sandsynligvis umuligt i tilfælde af programmeringsfejl, men for at sende fejlmeddelelsen til udviklerne.
-They work like this:
+Der er også web-tjenester, der leverer fejllogning for sådanne tilfælde, som eller .
-1. We register at the service and get a piece of JS (or a script URL) from them to insert on pages.
-2. That JS script sets a custom `window.onerror` function.
-3. When an error occurs, it sends a network request about it to the service.
-4. We can log in to the service web interface and see errors.
+De virker sådan her:
+1.Vi registrerer os hos services og får et stykke JS-kode (eller en URL til et script) fra dem til at indsætte på sider.
+2. Dette JS-script sætter en brugerdefineret `window.onerror` funktion.
+3. Når der sker en fejl, sender den en network request omkring det til tjenesten.
+4. Vi kan så logge ind på tjenestens webinterface og se fejl.
-## Summary
+## Opsummering
-The `try...catch` construct allows to handle runtime errors. It literally allows to "try" running the code and "catch" errors that may occur in it.
+Konstruktionen `try...catch` tillade os at håndtere runtime-fejl. Det tillader os bogstaveligt talt at "prøve" at køre koden og "fange" fejl, der kan opstå i den.
-The syntax is:
+Syntaksen er:
```js
try {
- // run this code
+ // kør denne kode
} catch (err) {
- // if an error happened, then jump here
- // err is the error object
+ // hvis der sker en fejl, så hop hertil
+ // err er et objekt der indeholder fejlinformationen
} finally {
- // do in any case after try/catch
+ // gør dette uanset om der sker en fejl eller ej
}
```
-There may be no `catch` section or no `finally`, so shorter constructs `try...catch` and `try...finally` are also valid.
+Der behøver ikke at være en `catch` klausul eller en `finally` klausul, så kortere konstruktioner `try...catch` og `try...finally` er også gyldige.
-Error objects have following properties:
+Error objekter har følgende egenskaber:
-- `message` -- the human-readable error message.
-- `name` -- the string with error name (error constructor name).
-- `stack` (non-standard, but well-supported) -- the stack at the moment of error creation.
+- `message` -- fejlmeddelelsen.
+- `name` -- strengen med fejlnavnet (konstruktoren navn).
+- `stack` (ikke-standard, men ret udbredt) -- stakken ved øjeblikket for fejl oprettelsen.
-If an error object is not needed, we can omit it by using `catch {` instead of `catch (err) {`.
+Hvis vi ikke behøver et error object, kan du udelade det ved at bruge `catch {` i stedet for `catch (err) {`.
-We can also generate our own errors using the `throw` operator. Technically, the argument of `throw` can be anything, but usually it's an error object inheriting from the built-in `Error` class. More on extending errors in the next chapter.
+Vi kan også generere vores egne fejl ved hjælp af `throw` operatoren. Teknisk set kan argumentet for `throw` være hvad som helst, men normalt er det et error object, der nedarver fra den indbyggede `Error` klasse. Mere om at udvide fejl i næste kapitel.
-*Rethrowing* is a very important pattern of error handling: a `catch` block usually expects and knows how to handle the particular error type, so it should rethrow errors it doesn't know.
+*Rethrowing* er en meget vigtig mønster for fejlhåndtering: en `catch` blok forventes typisk at vide, hvordan den skal håndtere den specifikke fejltype, så den bør kaste fejlen igen, hvis den ikke kender til den.
-Even if we don't have `try...catch`, most environments allow us to setup a "global" error handler to catch errors that "fall out". In-browser, that's `window.onerror`.
+Selv hvis vi ikke har `try...catch`, tillader de fleste miljøer os at opsætte en "global" fejlhåndtering for at fange fejl, der "falder ud". I browseren er det `window.onerror`.
diff --git a/1-js/10-error-handling/1-try-catch/try-catch-flow.svg b/1-js/10-error-handling/1-try-catch/try-catch-flow.svg
index 2c0d71348..336936c37 100644
--- a/1-js/10-error-handling/1-try-catch/try-catch-flow.svg
+++ b/1-js/10-error-handling/1-try-catch/try-catch-flow.svg
@@ -1 +1,91 @@
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/1-js/10-error-handling/2-custom-errors/1-format-error/solution.md b/1-js/10-error-handling/2-custom-errors/1-format-error/solution.md
index 754e68f9a..57109386d 100644
--- a/1-js/10-error-handling/2-custom-errors/1-format-error/solution.md
+++ b/1-js/10-error-handling/2-custom-errors/1-format-error/solution.md
@@ -6,9 +6,9 @@ class FormatError extends SyntaxError {
}
}
-let err = new FormatError("formatting error");
+let err = new FormatError("formattingsfejl");
-alert( err.message ); // formatting error
+alert( err.message ); // formatteringsfejl
alert( err.name ); // FormatError
alert( err.stack ); // stack
diff --git a/1-js/10-error-handling/2-custom-errors/1-format-error/task.md b/1-js/10-error-handling/2-custom-errors/1-format-error/task.md
index 2c8e910fc..8886e2cb1 100644
--- a/1-js/10-error-handling/2-custom-errors/1-format-error/task.md
+++ b/1-js/10-error-handling/2-custom-errors/1-format-error/task.md
@@ -2,21 +2,21 @@ importance: 5
---
-# Inherit from SyntaxError
+# Nedarv fra SyntaxError
-Create a class `FormatError` that inherits from the built-in `SyntaxError` class.
+Opret en klasse `FormatError` som nedarver fra den indbyggede `SyntaxError`-klasse.
-It should support `message`, `name` and `stack` properties.
+Den bør understøtte `message`, `name` og `stack` egenskaber.
-Usage example:
+Brugseksempel:
```js
-let err = new FormatError("formatting error");
+let err = new FormatError("formatteringsfejl");
-alert( err.message ); // formatting error
+alert( err.message ); // formatteringsfejl
alert( err.name ); // FormatError
alert( err.stack ); // stack
alert( err instanceof FormatError ); // true
-alert( err instanceof SyntaxError ); // true (because inherits from SyntaxError)
+alert( err instanceof SyntaxError ); // true (fordi den nedarver fra SyntaxError)
```
diff --git a/1-js/10-error-handling/2-custom-errors/article.md b/1-js/10-error-handling/2-custom-errors/article.md
index d28b07439..40531977d 100644
--- a/1-js/10-error-handling/2-custom-errors/article.md
+++ b/1-js/10-error-handling/2-custom-errors/article.md
@@ -1,42 +1,42 @@
-# Custom errors, extending Error
+# Brugerdefinerede fejl, udvidelse af Error
-When we develop something, we often need our own error classes to reflect specific things that may go wrong in our tasks. For errors in network operations we may need `HttpError`, for database operations `DbError`, for searching operations `NotFoundError` and so on.
+Når vi udvikler noget, har vi ofte brug for egne fejlklasser til at reflektere specifikke ting, der kan gå galt i vores opgaver. For fejl i netværksoperationer kan vi have brug for `HttpError`, for databaseoperationer `DbError`, for søgeoperationer `NotFoundError` og så videre.
-Our errors should support basic error properties like `message`, `name` and, preferably, `stack`. But they also may have other properties of their own, e.g. `HttpError` objects may have a `statusCode` property with a value like `404` or `403` or `500`.
+Vores fejl bør understøtte grundlæggende fejl egenskaber som `message`, `name` og meget gerne `stack`. Men de kan også have andre egenskaber af deres egen type, f.eks. `HttpError` objekter kan have en `statusCode` egenskab med en værdi som `404` eller `403` eller `500`.
-JavaScript allows to use `throw` with any argument, so technically our custom error classes don't need to inherit from `Error`. But if we inherit, then it becomes possible to use `obj instanceof Error` to identify error objects. So it's better to inherit from it.
+JavaScript tillader at bruge `throw` med ethvert argument, så teknisk set behøver vores custom error klasser ikke at arve fra `Error`. Men hvis vi arver, så bliver det muligt at bruge `obj instanceof Error` til at identificere fejl objekter. Så det er bedre at arve fra den.
-As the application grows, our own errors naturally form a hierarchy. For instance, `HttpTimeoutError` may inherit from `HttpError`, and so on.
+Efterhånden som applikationen vokser, vil vores egne fejl naturligvis danne en hierarki. For eksempel kan `HttpTimeoutError` arve fra `HttpError`, og så videre.
-## Extending Error
+## Udvidelse af Error
-As an example, let's consider a function `readUser(json)` that should read JSON with user data.
+Som et eksempel, lad os overveje en funktion `readUser(json)` som skal læse JSON med brugerdata.
-Here's an example of how a valid `json` may look:
+Her er et eksempel på, hvordan et gyldigt `json` kan se ud:
```js
let json = `{ "name": "John", "age": 30 }`;
```
-Internally, we'll use `JSON.parse`. If it receives malformed `json`, then it throws `SyntaxError`. But even if `json` is syntactically correct, that doesn't mean that it's a valid user, right? It may miss the necessary data. For instance, it may not have `name` and `age` properties that are essential for our users.
+Internt bruger vi `JSON.parse`. Hvis den modtager fejlformateret `json`, så kaster den `SyntaxError`. Men selv hvis `json` er syntaktisk korrekt, betyder det jo ikke nødvendigvis, at det er en gyldig bruger? Det kan mangle de nødvendige data. For eksempel kan det ikke have `name` og `age` egenskaber, som er afgørende for vores brugere.
-Our function `readUser(json)` will not only read JSON, but check ("validate") the data. If there are no required fields, or the format is wrong, then that's an error. And that's not a `SyntaxError`, because the data is syntactically correct, but another kind of error. We'll call it `ValidationError` and create a class for it. An error of that kind should also carry the information about the offending field.
+Vores funktion `readUser(json)` vil ikke kun læse JSON, men også tjekke ("validere") dataene. Hvis der mangler at blive udfyldt påkrævede felter, eller det er formatet er forkert, så er det en fejl. Og det er ikke en `SyntaxError`, fordi dataene er syntaktisk korrekte, men en anden type af fejl. Vi vil kalde det `ValidationError` og oprette en klasse til det. En fejl af denne type bør også bære informationen om det fejlbehagende felt.
-Our `ValidationError` class should inherit from the `Error` class.
+Vores `ValidationError` klasse bør arve fra `Error` klassen.
-The `Error` class is built-in, but here's its approximate code so we can understand what we're extending:
+Klassen `Error` er indbygget, men her er dens omtrentlige kode, så vi kan forstå, hvad vi udvider:
```js
-// The "pseudocode" for the built-in Error class defined by JavaScript itself
+// "pseudocode" for den indbyggede Error klasse defineret af JavaScript selv
class Error {
constructor(message) {
this.message = message;
- this.name = "Error"; // (different names for different built-in error classes)
- this.stack = ; // non-standard, but most environments support it
+ this.name = "Error"; // (forskellige navne for forskellige indbyggede fejltyper)
+ this.stack = ; // ikke-standard, men de fleste miljøer understøtter det
}
}
```
-Now let's inherit `ValidationError` from it and try it in action:
+Lad nu `ValidationError` udvide denne `Error` og prøve at bruge den:
```js run
*!*
@@ -49,23 +49,23 @@ class ValidationError extends Error {
}
function test() {
- throw new ValidationError("Whoops!");
+ throw new ValidationError("Ups!");
}
try {
test();
} catch(err) {
- alert(err.message); // Whoops!
+ alert(err.message); // Ups!
alert(err.name); // ValidationError
- alert(err.stack); // a list of nested calls with line numbers for each
+ alert(err.stack); // en liste af indlejrede kald med linjenumre for hvor fejlen opstod
}
```
-Please note: in the line `(1)` we call the parent constructor. JavaScript requires us to call `super` in the child constructor, so that's obligatory. The parent constructor sets the `message` property.
+Bemærk: i linjen `(1)` kalder vi 'parent constructor'. JavaScript kræver at vi kalder `super` i 'child constructor', så det er obligatorisk. Forældrekonstruktøren sætter `message` egenskaben.
-The parent constructor also sets the `name` property to `"Error"`, so in the line `(2)` we reset it to the right value.
+Forældrekonstruktøren sætter også `name` egenskaben til `"Error"`, så i linjen `(2)` nulstiller vi den til den rigtige værdi.
-Let's try to use it in `readUser(json)`:
+Lad os prøve at bruge den i `readUser(json)`:
```js run
class ValidationError extends Error {
@@ -80,52 +80,52 @@ function readUser(json) {
let user = JSON.parse(json);
if (!user.age) {
- throw new ValidationError("No field: age");
+ throw new ValidationError("Mangler feltet: age");
}
if (!user.name) {
- throw new ValidationError("No field: name");
+ throw new ValidationError("Mangler feltet: name");
}
return user;
}
-// Working example with try..catch
+// Eksempel med try..catch
try {
let user = readUser('{ "age": 25 }');
} catch (err) {
if (err instanceof ValidationError) {
*!*
- alert("Invalid data: " + err.message); // Invalid data: No field: name
+ alert("Ugyldige data: " + err.message); // Ugyldige data: Mangler feltet: name
*/!*
} else if (err instanceof SyntaxError) { // (*)
- alert("JSON Syntax Error: " + err.message);
+ alert("JSON Syntaksfejl: " + err.message);
} else {
- throw err; // unknown error, rethrow it (**)
+ throw err; // ukendt fejl, kast den videre (**)
}
}
```
-The `try..catch` block in the code above handles both our `ValidationError` and the built-in `SyntaxError` from `JSON.parse`.
+Blokken `try..catch` i koden ovenfor åndterer både vores `ValidationError` og den indbyggede `SyntaxError` fra `JSON.parse`.
-Please take a look at how we use `instanceof` to check for the specific error type in the line `(*)`.
+Se hvordan vi gør brug af `instanceof` til at tjekke for den specifikke fejltype i linjen `(*)`.
-We could also look at `err.name`, like this:
+Vi kan også kigge på `err.name`, sådan her:
```js
// ...
-// instead of (err instanceof SyntaxError)
+// i stedet for (err instanceof SyntaxError)
} else if (err.name == "SyntaxError") { // (*)
// ...
```
-The `instanceof` version is much better, because in the future we are going to extend `ValidationError`, make subtypes of it, like `PropertyRequiredError`. And `instanceof` check will continue to work for new inheriting classes. So that's future-proof.
+`instanceof` versionen er meget bedre, fordi vi i fremtiden måske vil udvide `ValidationError`, lave undertyper af den i stil med `PropertyRequiredError`. Et tjek med `instanceof` vil stadig virke for nedarvede klasser. På den måde er det fremtidssikret.
-Also it's important that if `catch` meets an unknown error, then it rethrows it in the line `(**)`. The `catch` block only knows how to handle validation and syntax errors, other kinds (caused by a typo in the code or other unknown reasons) should fall through.
+Det er også vigtigt, at hvis `catch` møder en ukendt fejl, så kaster den den videre i linjen `(**)`. Denne `catch` blok ved kun hvordan vi håndterer validerings- og syntaksfejl. Alt andet (sket ved en fejl i koden eller andre ukendte årsager) skal falde igennem.
-## Further inheritance
+## Videre nedarvning
-The `ValidationError` class is very generic. Many things may go wrong. The property may be absent or it may be in a wrong format (like a string value for `age` instead of a number). Let's make a more concrete class `PropertyRequiredError`, exactly for absent properties. It will carry additional information about the property that's missing.
+Klassen `ValidationError` er meget generisk - mange ting kan gå galt. Egenskaben kan mangle eller den kan være i et forkert format (som en strengværdi for `age` i stedet for et tal). Lad os lave en mere konkret klasse `PropertyRequiredError`, præcist til at håndtere manglende egenskaber. Den vil bære yderligere information om den egenskab, der mangler.
```js run
class ValidationError extends Error {
@@ -138,7 +138,7 @@ class ValidationError extends Error {
*!*
class PropertyRequiredError extends ValidationError {
constructor(property) {
- super("No property: " + property);
+ super("Mangler egenskab: " + property);
this.name = "PropertyRequiredError";
this.property = property;
}
@@ -159,32 +159,32 @@ function readUser(json) {
return user;
}
-// Working example with try..catch
+// Eksempel med try..catch
try {
let user = readUser('{ "age": 25 }');
} catch (err) {
if (err instanceof ValidationError) {
*!*
- alert("Invalid data: " + err.message); // Invalid data: No property: name
+ alert("Ugyldige data: " + err.message); // Ugyldige data: Mangler egenskab: name
alert(err.name); // PropertyRequiredError
alert(err.property); // name
*/!*
} else if (err instanceof SyntaxError) {
- alert("JSON Syntax Error: " + err.message);
+ alert("JSON Syntaksfejl: " + err.message);
} else {
- throw err; // unknown error, rethrow it
+ throw err; // ukendt fejl, kast den videre
}
}
```
-The new class `PropertyRequiredError` is easy to use: we only need to pass the property name: `new PropertyRequiredError(property)`. The human-readable `message` is generated by the constructor.
+Den nye klasse `PropertyRequiredError` er nem at bruge: vi behøver bare at videregive egenskabens navn: `new PropertyRequiredError(property)`. Den læsevenlige `message` bliver skabt i konstruktøren.
-Please note that `this.name` in `PropertyRequiredError` constructor is again assigned manually. That may become a bit tedious -- to assign `this.name = ` in every custom error class. We can avoid it by making our own "basic error" class that assigns `this.name = this.constructor.name`. And then inherit all our custom errors from it.
+Bemærk at `this.name` in `PropertyRequiredError` constructor er igen tildelt manuelt. Det kan blive en smule besværligt -- at tildele `this.name = ` i hver custom error klasse. Vi kan undgå det ved at lave vores egen "basic error" klasse, der tildele `this.name = this.constructor.name`. Og så nedarve alle vores custom errors fra den.
-Let's call it `MyError`.
+Lad os kalde det `MyError`.
-Here's the code with `MyError` and other custom error classes, simplified:
+Her er koden med `MyError` og andre custom error klasser, forenklet:
```js run
class MyError extends Error {
@@ -200,56 +200,56 @@ class ValidationError extends MyError { }
class PropertyRequiredError extends ValidationError {
constructor(property) {
- super("No property: " + property);
+ super("Ingen egenskab: " + property);
this.property = property;
}
}
-// name is correct
+// name er korrekt indstillet af MyError
alert( new PropertyRequiredError("field").name ); // PropertyRequiredError
```
-Now custom errors are much shorter, especially `ValidationError`, as we got rid of the `"this.name = ..."` line in the constructor.
+Nu er brugerdefinerede fejl meget kortere, især `ValidationError`, da vi har fjernet linjen `"this.name = ..."` i constructor.
-## Wrapping exceptions
+## Indpakning af undtagelser (expeptions)
-The purpose of the function `readUser` in the code above is "to read the user data". There may occur different kinds of errors in the process. Right now we have `SyntaxError` and `ValidationError`, but in the future `readUser` function may grow and probably generate other kinds of errors.
+Meningen med funktionen `readUser` i koden ovenfor er "at læse brugerdata". Der kan opstå forskellige slags fejl i den proces. Som det er nu har vi `SyntaxError` og `ValidationError`, men i en fremtidig `readUser` funktion kan det vokse og måske generere andre typer fejl.
-The code which calls `readUser` should handle these errors. Right now it uses multiple `if`s in the `catch` block, that check the class and handle known errors and rethrow the unknown ones.
+Koden der kalder `readUser` bør håndtere disse fejl. Lige nu bruger den flere `if` inde i `catch` blokken, der tjekker klassen og håndterer kendte fejl og kaster de ukendte videre.
-The scheme is like this:
+Skemaet er sådan her:
```js
try {
...
- readUser() // the potential error source
+ readUser() // den potentielle fejlkilde
...
} catch (err) {
if (err instanceof ValidationError) {
- // handle validation errors
+ // håndter valideringsfejl
} else if (err instanceof SyntaxError) {
- // handle syntax errors
+ // håndter syntaksfejl
} else {
- throw err; // unknown error, rethrow it
+ throw err; // ukendt fejl, kast den videre
}
}
```
-In the code above we can see two types of errors, but there can be more.
+I koden ovenfor kan vi se to typer af fejl, men der kan være flere.
-If the `readUser` function generates several kinds of errors, then we should ask ourselves: do we really want to check for all error types one-by-one every time?
+Hvis `readUser`-funktionen genererer flere typer af fejl, så bør vi spørge os selv: vil vi virkelig have lyst til at skulle tjekke for alle fejltyper - en efter en - hver gang?
-Often the answer is "No": we'd like to be "one level above all that". We just want to know if there was a "data reading error" -- why exactly it happened is often irrelevant (the error message describes it). Or, even better, we'd like to have a way to get the error details, but only if we need to.
+Ofte er svaret "Nej": vi vil gerne være "et niveau over alt det". Vi vil bare have at vide om der var en "data læsningsfejl" -- hvorfor det præcist skete er ofte irrelevant (fejlmeddelelsen beskriver det). Eller, endnu bedre, vi vil gerne have en måde at få detaljerne om fejlen på ... men kun hvis vi har brug for dem.
-The technique that we describe here is called "wrapping exceptions".
+Den teknik vi beskriver her kaldes "wrapping exceptions".
-1. We'll make a new class `ReadError` to represent a generic "data reading" error.
-2. The function `readUser` will catch data reading errors that occur inside it, such as `ValidationError` and `SyntaxError`, and generate a `ReadError` instead.
-3. The `ReadError` object will keep the reference to the original error in its `cause` property.
+1. Vi laver en ny klasse `ReadError` til at repræsentere en generisk "data læsning" fejl.
+2. Funktionen `readUser` vil fange data læsningsfejl, der opstår inden for den, såsom `ValidationError` og `SyntaxError`, og generere en `ReadError` i stedet.
+3. `ReadError`-objektet vil gemme referencen til den originale fejl i sin `cause`-egenskab.
-Then the code that calls `readUser` will only have to check for `ReadError`, not for every kind of data reading errors. And if it needs more details of an error, it can check its `cause` property.
+Således vil koden, der kalder `readUser`, kun behøve at tjekke for `ReadError`, ikke for hver enkelt type data læsningsfejl. Og hvis den har brug for flere detaljer om en fejl, kan den tjekke dens `cause`-egenskab.
-Here's the code that defines `ReadError` and demonstrates its use in `readUser` and `try..catch`:
+Her er koden, der definerer `ReadError` og demonstrerer dens brug i `readUser` og `try..catch`:
```js run
class ReadError extends Error {
@@ -281,7 +281,7 @@ function readUser(json) {
} catch (err) {
*!*
if (err instanceof SyntaxError) {
- throw new ReadError("Syntax Error", err);
+ throw new ReadError("Syntaksfejl", err);
} else {
throw err;
}
@@ -293,7 +293,7 @@ function readUser(json) {
} catch (err) {
*!*
if (err instanceof ValidationError) {
- throw new ReadError("Validation Error", err);
+ throw new ReadError("Valideringsfejl", err);
} else {
throw err;
}
@@ -317,14 +317,14 @@ try {
}
```
-In the code above, `readUser` works exactly as described -- catches syntax and validation errors and throws `ReadError` errors instead (unknown errors are rethrown as usual).
+I koden ovenfor fungerer `readUser` præcis som beskrevet -- fanger syntaks- og valideringsfejl og kaster `ReadError`-fejl i stedet (ukendte fejl kastes videre som normalt).
-So the outer code checks `instanceof ReadError` and that's it. No need to list all possible error types.
+Så den ydre kode tjekker `instanceof ReadError` og det er det. Ingen grund til at gennemgå alle mulige fejltyper.
-The approach is called "wrapping exceptions", because we take "low level" exceptions and "wrap" them into `ReadError` that is more abstract. It is widely used in object-oriented programming.
+Den kaldes "wrapping exceptions", fordi den tager "low level" undtagelser og "pakker" dem ind i `ReadError` der er mere abstrakt. Denne teknik er meget brugt i objektorienteret programmering.
-## Summary
+## Opsummering
-- We can inherit from `Error` and other built-in error classes normally. We just need to take care of the `name` property and don't forget to call `super`.
-- We can use `instanceof` to check for particular errors. It also works with inheritance. But sometimes we have an error object coming from a 3rd-party library and there's no easy way to get its class. Then `name` property can be used for such checks.
-- Wrapping exceptions is a widespread technique: a function handles low-level exceptions and creates higher-level errors instead of various low-level ones. Low-level exceptions sometimes become properties of that object like `err.cause` in the examples above, but that's not strictly required.
+- Vi kan nedarve fra `Error` og andre indbyggede fejltyper på normal vis. Vi skal bare tage huske på `name`-egenskaben og ikke glemme at kalde `super`.
+- Vi kan bruge `instanceof` til at tjekke for bestemte fejl. Det virker også med nedarvning. Men nogle gange har vi et fejlobjekt, der kommer fra en 3.parts bibliotek, hvor der måske ikke er en enkel måde at få dens klasse. Her kan `name`-egenskaben bruges til sådanne tjek.
+- Wrapping exceptions er en almindelig teknik: en funktion håndterer lav-niveau undtagelser og opretter højere-niveau fejl i stedet for forskellige lav-niveau fejl. Lav-niveau undtagelser bliver nogle gange til egenskaber på det objekt, som `err.cause` i eksemplerne ovenfor, men det er ikke strengt nødvendigt.
diff --git a/1-js/10-error-handling/index.md b/1-js/10-error-handling/index.md
index face61c6e..aa2db89c7 100644
--- a/1-js/10-error-handling/index.md
+++ b/1-js/10-error-handling/index.md
@@ -1 +1 @@
-# Error handling
+# Håndtering af fejl
diff --git a/1-js/11-async/01-callbacks/article.md b/1-js/11-async/01-callbacks/article.md
index 57115a909..754a3e42c 100644
--- a/1-js/11-async/01-callbacks/article.md
+++ b/1-js/11-async/01-callbacks/article.md
@@ -1,68 +1,66 @@
+# Introduktion: callbacks
+```warn header="Vi bruger browser metoder i eksemplerne her"
+For at demonstrere brugen af callbacks, promises og andre abstrakte koncepter, vil vi bruge nogle browser metoder: specifikt, indlæsning af scripts og udførelse af simple manipulationer af dokumentet.
-# Introduction: callbacks
+Hvis du ikke er fortrolig med disse metoder, og brugen af dem i eksemplerne er forvirrende, kan du med fordel læse et par kapitler fra den [næste del](/document) af tutorialen.
-```warn header="We use browser methods in examples here"
-To demonstrate the use of callbacks, promises and other abstract concepts, we'll be using some browser methods: specifically, loading scripts and performing simple document manipulations.
-
-If you're not familiar with these methods, and their usage in the examples is confusing, you may want to read a few chapters from the [next part](/document) of the tutorial.
-
-Although, we'll try to make things clear anyway. There won't be anything really complex browser-wise.
+Vi vil dog forsøge at gøre tingene så simple og klare som muligt. Der vil ikke være noget virkelig komplekst browser-baseret.
```
-Many functions are provided by JavaScript host environments that allow you to schedule *asynchronous* actions. In other words, actions that we initiate now, but they finish later.
+Mange funktioner leveret af JavaScript host miljøer tillader dig at planlægge *asynkrone* handlinger. Med andre ord, handlinger som vi starter nu, men de afsluttes senere.
-For instance, one such function is the `setTimeout` function.
+For eksempel, en sådan funktion er `setTimeout` funktionen.
-There are other real-world examples of asynchronous actions, e.g. loading scripts and modules (we'll cover them in later chapters).
+Der er andre eksempler på asynkrone handlinger i den virkelige verden, f.eks. indlæsning af scripts og moduler (vi vil dække dem i senere kapitler).
-Take a look at the function `loadScript(src)`, that loads a script with the given `src`:
+Tag et kig på funktionen `loadScript(src)`, som loader et script med det givne `src`:
```js
function loadScript(src) {
- // creates a
-
-
-