This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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];
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;
Expand All
@@ -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.
// 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 {}
Expand All
@@ -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
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;
Expand All
@@ -186,33 +186,33 @@ 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:
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.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Class checking: "instanceof" #272
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Class checking: "instanceof" #272
Filter by extension
Viewed files
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There are no files selected for viewing