Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Class checking: "instanceof"#187

New issue

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
otmon76 merged 3 commits intojavascript-tutorial:masterfromotmon76:1.9.6
Jun 4, 2025
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
Yeah, looks strange indeed.
Ano, určitě to vypadá podivně.

But `instanceof`does not care about the function, but rather about its `prototype`,that it matches against the prototype chain.
Ale `instanceof`se nezajímá o funkci, nýbrž jen o její `prototype`,který porovnává s prototypovým řetězcem.

And here`a.__proto__ == B.prototype`,so `instanceof`returns `true`.
A zde je`a.__proto__ == B.prototype`,takže `instanceof`vrátí `true`.

So, by the logic of`instanceof`, the `prototype` actually defines the type, not the constructor function.
Podle logiky`instanceof` je tedy typ ve skutečnosti definován vlastností `prototype`, ne samotným konstruktorem.
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,9 +2,9 @@ importance: 5

---

#Strange instanceof
#Podivné instanceof

In the code below, why does`instanceof`return `true`?We can easily see that`a`is not created by `B()`.
Proč v následujícím kódu`instanceof`vrací `true`?Vidíme přece, že`a`není vytvořeno pomocí `B()`.

```js run
function A() {}
Expand Down
190 changes: 95 additions & 95 deletions1-js/09-classes/06-instanceof/article.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,168 +1,168 @@
#Class checking: "instanceof"
#Ověřování tříd: „instanceof

The `instanceof`operator allows to check whether an object belongs to a certain class. It also takes inheritance into account.
Operátor `instanceof`umožňuje ověřit, zda objekt patří do určité třídy. Bere v úvahu i dědičnost.

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.
Toto ověření může být zapotřebí v mnoha případech. Například může být použito k vytvoření *polymorfní* funkce, takové, která zachází se svými argumenty různě v závislosti na jejich typu.

##The instanceof operator [#ref-instanceof]
##Operátor instanceof [#ref-instanceof]

The syntax is:
Syntaxe je:
```js
obj instanceofClass
obj instanceofTřída
```

It returns`true` if `obj`belongs to the `Class` or a class inheriting from it.
Vrací`true`, jestliže `obj`patří do třídy `Třída` nebo do třídy, která je z ní zděděna.

For instance:
Například:

```js run
classRabbit {}
letrabbit = newRabbit();
classKrálík {}
letkrálík = newKrálík();

//is it an object of Rabbit class?
//je to objekt třídy Králík?
*!*
alert(rabbit instanceofRabbit ); // true
alert(králík instanceofKrálík ); // true
*/!*
```

It also works with constructor functions:
Funguje to i pro konstruktory:

```js run
*!*
//instead of class
functionRabbit() {}
//namísto třídy
functionKrálík() {}
*/!*

alert( newRabbit() instanceofRabbit ); // true
alert( newKrálík() instanceofKrálík ); // true
```

...And with built-in classes like `Array`:
...A pro zabudované třídy jako `Array`:

```js run
letarr = [1, 2, 3];
alert(arr instanceof Array ); // true
alert(arr instanceof Object ); // true
letpole = [1, 2, 3];
alert(pole instanceof Array ); // true
alert(pole instanceof Object ); // true
```

Please note that `arr` also belongs to the `Object` class. That's because`Array`prototypically inherits from `Object`.
Prosíme všimněte si, že `pole` patří i do třídy `Object`. Je to proto, že třída`Array`je prototypově zděděna z třídy `Object`.

Normally, `instanceof`examines the prototype chain for the check. We can also set a custom logic in the static method `Symbol.hasInstance`.
Normálně `instanceof`při ověřování prozkoumává prototypový řetězec. Můžeme si však také nastavit vlastní logiku ve statické metodě `Symbol.hasInstance`.

The algorithm of`obj instanceofClass` works roughly as follows:
Algoritmus operátoru`obj instanceofTřída` funguje zhruba následovně:

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.Pokud existuje statická metoda`Symbol.hasInstance`,pak ji jen zavolá: `Třída[Symbol.hasInstance](obj)`.Ta by měla vrátit buď`true`, nebo `false`,a jsme hotovi. Tímto způsobem si můžeme chování`instanceof` sami nastavit.

For example:
Například:

```js run
//setupinstanceOfcheck that assumes that
//anything with canEat property is an animal
classAnimal {
//nastavíme ověřeníinstanceOftak, aby předpokládalo,
//že všechno, co má vlastnost můžeŽrát, je zvíře
classZvíře {
static [Symbol.hasInstance](obj) {
if (obj.canEat) return true;
if (obj.můžeŽrát) return true;
}
}

let obj = {canEat: true };
let obj = {můžeŽrát: true };

alert(obj instanceofAnimal); // true:Animal[Symbol.hasInstance](obj) is called
alert(obj instanceofZvíře); // true:zavolá se Zvíře[Symbol.hasInstance](obj)
```

2.Most classes do not have`Symbol.hasInstance`.In that case, the standard logic is used: `obj instanceOfClass` checks whether `Class.prototype`is equal to one of the prototypes in the`obj` prototype chain.
2.Většina tříd nemá`Symbol.hasInstance`.V tom případě je použita standardní logika: `obj instanceOfTřída` zjistí, zda se `Třída.prototype`rovná některému z prototypů v prototypovém řetězci objektu`obj`.

In other words, compare one after another:
Jinými slovy, porovnává jeden po druhém:
```js
obj.__proto__ ===Class.prototype?
obj.__proto__.__proto__ ===Class.prototype?
obj.__proto__.__proto__.__proto__ ===Class.prototype?
obj.__proto__ ===Třída.prototype?
obj.__proto__.__proto__ ===Třída.prototype?
obj.__proto__.__proto__.__proto__ ===Třída.prototype?
...
//if any answer istrue,return true
//otherwise, if we reached the end of the chain, return false
//je-li kterákoli odpověďtrue,vrátí true
//jinak, pokud jsme dosáhli konce řetězce, vrátí false
```

In the example above `rabbit.__proto__ ===Rabbit.prototype`,so that gives the answer immediately.
V uvedeném příkladu `králík.__proto__ ===Králík.prototype`,takže odpověď je vydána okamžitě.

In the case of an inheritance, the match will be at the second step:
V případě dědičnosti bude shoda nalezena ve druhém kroku:

```js run
classAnimal {}
classRabbit extendsAnimal {}
classZvíře {}
classKrálík extendsZvíře {}

letrabbit = newRabbit();
letkrálík = newKrálík();
*!*
alert(rabbit instanceofAnimal); // true
alert(králík instanceofZvíře); // true
*/!*

//rabbit.__proto__ ===Animal.prototype (no match)
//králík.__proto__ ===Zvíře.prototype (není shoda)
*!*
//rabbit.__proto__.__proto__ ===Animal.prototype (match!)
//králík.__proto__.__proto__ ===Zvíře.prototype (shoda!)
*/!*
```

Here's the illustration of what `rabbit instanceofAnimal` compares with `Animal.prototype`:
Na tomto obrázku je vidět, co `králík instanceofZvíře` porovnává se `Zvíře.prototype`:

![](instanceof.svg)

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 instanceofClass` can be rephrased as `Class.prototype.isPrototypeOf(obj)`.
Mimochodem, existuje také metoda[objA.isPrototypeOf(objB)](mdn:js/object/isPrototypeOf),která vrátí `true`, jestliže se`objA`nachází někde v prototypovém řetězci objektu`objB`.Test`obj instanceofTřída` tedy lze přepsat na `Třída.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.
Veselé je, že samotný konstruktor `Třída` se na ověřování nepodílí! Záleží jen na prototypovém řetězci a na `Třída.prototype`.

That can lead to interesting consequences when a`prototype`property is changed after the object is created.
To může vést k zajímavým důsledkům, když je vlastnost`prototype`změněna po vytvoření objektu.

Like here:
Například zde:

```js run
functionRabbit() {}
letrabbit = newRabbit();
functionKrálík() {}
letkrálík = newKrálík();

//changed the prototype
Rabbit.prototype = {};
//změníme prototyp
Králík.prototype = {};

// ...not a rabbit any more!
// ...už to není králík!
*!*
alert(rabbit instanceofRabbit ); // false
alert(králík instanceofKrálík ); // false
*/!*
```

## Bonus: Object.prototype.toStringfor the type
## Bonus: Object.prototype.toStringpro typ

We already know that plain objects are converted to string as `[object Object]`:
Už víme, že plané objekty se převádějí na řetězec jako `[object Object]`:

```js run
let obj = {};

alert(obj); // [object Object]
alert(obj.toString()); //the same
alert(obj.toString()); //totéž
```

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`.
Taková je jejich implementace metody`toString`.Existuje však skrytá vlastnost, která činí`toString`ve skutečnosti mnohem silnější. Můžeme ji používat jako rozšířený`typeof`a alternativu pro `instanceof`.

Sounds strange? Indeed. Let's demystify.
Zní to zvláštně? Určitě ano. Odhalme to.

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.
Podle [specifikace](https://tc39.github.io/ecma262/#sec-object.prototype.tostring) může být vestavěný`toString`extrahován z objektu a spuštěn v kontextu jakékoli jiné hodnoty. A na oné hodnotě pak závisí jeho výsledek.

-For a number, it will be `[object Number]`
-For aboolean, it will be `[object Boolean]`
-For `null`: `[object Null]`
-For `undefined`: `[object Undefined]`
-For arrays: `[object Array]`
- ...etc (customizable).
-Pro číslo to bude `[object Number]`
-Proboolean to bude `[object Boolean]`
-Pro `null`: `[object Null]`
-Pro `undefined`: `[object Undefined]`
-Pro pole: `[object Array]`
- ...atd. (nastavitelně).

Let's demonstrate:
Předveďme si to:

```js run
//copy toString method into a variable for convenience
letobjectToString = Object.prototype.toString;
//pro přehlednost si zkopírujeme metodu toString do proměnné
letmetodaToString = Object.prototype.toString;

//what type is this?
letarr = [];
//jakého typu je tohle?
letpole = [];

alert(objectToString.call(arr) ); // [object *!*Array*/!*]
alert(metodaToString.call(pole) ); // [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`.
Zde jsme použili metodu[call](mdn:js/function/call), popsanou v kapitole[](info:call-apply-decorators), ke spuštění funkce `metodaToString` v kontextu`this=pole`.

Internally, the`toString`algorithm examines`this`and returns the corresponding result. More examples:
Vnitřně algoritmus metody`toString`prozkoumává`this`a vrací odpovídající výsledek. Další příklady:

```js run
let s = Object.prototype.toString;
Expand All@@ -174,45 +174,45 @@ alert( s.call(alert) ); // [object Function]

### Symbol.toStringTag

The behavior of Object`toString`can be customized using a special object property `Symbol.toStringTag`.
Chování metody`toString`můžeme nastavit pomocí speciální objektové vlastnosti `Symbol.toStringTag`.

For instance:
Například:

```js run
letuser = {
[Symbol.toStringTag]: "User"
letuživatel = {
[Symbol.toStringTag]: "Uživatel"
};

alert( {}.toString.call(user) ); // [objectUser]
alert( {}.toString.call(uživatel) ); // [objectUživatel]
```

For most environment-specific objects, there is such a property. Here are some browser specific examples:
Tato vlastnost existuje u většiny objektů specifických pro určité prostředí. Uvedeme některé příklady specifické pro prohlížeč:

```js run
// toStringTagfor the environment-specific object and class:
// toStringTagv objektu a třídě specifické pro určité prostředí:
alert( window[Symbol.toStringTag]); // Window
alert( XMLHttpRequest.prototype[Symbol.toStringTag] ); // XMLHttpRequest

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 ...]`.
Jak vidíte, výsledkem je přesně`Symbol.toStringTag` (pokud existuje),zabalený do `[object ...]`.

At the end we have "typeofon steroids" that not only works for primitive data types, but also for built-in objects and even can be customized.
Nakonec tedy máme „typeofna steroidech“, který funguje nejen pro primitivní datové typy, ale i pro zabudované objekty a dokonce se dá nastavit.

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.
Když tedy chceme u vestavěných objektů zjistit název typu jako řetězec a ne ho jen ověřit, můžeme místo `instanceof` používat `{}.toString.call`.

##Summary
##Shrnutí

Let's summarize the type-checking methods that we know:
Shrňme si metody pro ověření typu, které známe:

| |works for |returns |
| |funguje pro |vrací |
|---------------|-------------|---------------|
| `typeof` |primitives |string |
| `{}.toString` |primitives, built-in objects, objects with `Symbol.toStringTag` |string |
| `instanceof` |objects | true/false |
| `typeof` |primitivy |řetězec |
| `{}.toString` |primitivy, vestavěné objekty, objekty se `Symbol.toStringTag` |řetězec |
| `instanceof` |objekty | true/false |

As we can see, `{}.toString`is technically a "more advanced" `typeof`.
Jak vidíme, `{}.toString`je technicky „pokročilejší“ `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.
A když pracujeme s třídní hierarchií a chceme si ověřit třídu, přičemž chceme vzít v úvahu dědičnost, opravdu se zaleskne operátor `instanceof`.
Loading

[8]ページ先頭

©2009-2025 Movatter.jp