Pourquoi ne pas instanceof travail sur les instances de l'Erreur de sous-classes, en vertu de babel-nœud?
Je vois que le instanceof
opérateur ne fonctionne pas sur les instances de Error
sous-classes, lors de l'exécution sous babel-nœud version 6.1.18/Node version 5.1.0 sur OS X. Pourquoi est-ce? Le même code fonctionne bien dans le navigateur, essayez mon violon pour un exemple.
Le code suivant sorties true
dans le navigateur, alors qu'en vertu de babel-nœud c'est faux:
class Sub extends Error {
}
let s = new Sub()
console.log(`The variable 's' is an instance of Sub: ${s instanceof Sub}`)
Je peux seulement imaginer que cela soit dû à un bogue dans babel-nœud, depuis instanceof
fonctionne pour d'autres classes de base que Error
.
.babelrc
{
"presets": ["es2015"]
}
Compilé Sortie
C'est le JavaScript compilé par babel 6.1.18:
'use strict';
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var Sub = (function (_Error) {
_inherits(Sub, _Error);
function Sub() {
_classCallCheck(this, Sub);
return _possibleConstructorReturn(this, Object.getPrototypeOf(Sub).apply(this, arguments));
}
return Sub;
})(Error);
var s = new Sub();
console.log('The variable \'s\' is an instance of Sub: ' + (s instanceof Sub));
- Je ne peux pas reproduire votre problème. J'ai testé les deux avec en ligne de babel repl et à l'aide de babel-nœud (au plus tard).
- Ce preset utilisez-vous avec Babel? Peut-être l'affichage de la transpiled script permettrait de reproduire le problème
- Merci, va vérifier plus loin.
- es2015
- Le violon utilise Babel dans le navigateur? Le point est que Babel fonctionne différemment dans le navigateur vs Nœud apparemment.
- J'ai posté le script compilé.
Vous devez vous connecter pour publier un commentaire.
tl;dr Si vous êtes sur Babel 6, vous pouvez utiliser https://www.npmjs.com/package/babel-plugin-transform-builtin-extend
Builtin extension des types comme
Array
etError
et telle n'a jamais été pris en charge dans Babel. Il est parfaitement valide dans un véritable ES6 environnement, mais il ya des exigences pour le faire fonctionner, qui sont très difficiles à transpile dans une manière qui est compatible avec les navigateurs plus anciens. Il "travaille" dans Babel 5 en ce qu'il ne renvoie pas d'erreur, mais les objets instanciés à partir de la prolongation de la sous-classe n'a pas fonctionné comme ils étaient censés le faire, par exemple:résultats dans
Alors qu'il n'a pas d'erreur, le sous-classe ne prend pas correctement en obtenir une "pile" comme les erreurs sont supposées le faire. De même, si vous étiez à étendre
Array
il peut se comporter un peu comme un tableau, et ont méthodes de tableau, mais il ne se comporte pas totalement comme un tableau.La Babel 5 documentation spécifiquement appelé cela comme un avantage-cas des classes d'être conscient de.
Dans Babel 6, les classes ont été modifiés pour être plus conformes aux spécifications de la façon de sous-classement est assurée, et l'effet secondaire est que maintenant le code ci-dessus encore pas de travail, mais il ne fonctionnera pas dans une manière différente qu'avant. Cela a été couvert https://phabricator.babeljs.io/T3083, mais vous en saurez plus ici sur une solution potentielle.
De retour de Babel 5 sous-classement de comportement (qui, rappelez-vous, n'est toujours pas droit ou recommandé), vous pouvez enrouler le builtin un constructeur dans votre propre temporaire de la classe, par exemple
Avec cette aide, plutôt que de faire de
ne
Dans votre cas particulier, cependant, vous avez dit que vous êtes sur le Nœud 5.x. Nœud 5 a un support natif pour les ES6 classes sans transpiling. Je vous recommandons d'utiliser ceux en laissant tomber le
es2015
preset et au lieu d'utilisernode5
de sorte que vous obtenez les classes natives, entre autres choses. Dans ce contexte,fonctionnera de la façon que vous attendez.
Pour les gens qui ne sur le Nœud 4/5, récents ou Chrome, vous pouvez envisager d'utiliser quelque chose comme https://www.npmjs.com/package/error. Vous pouvez aussi explorer https://www.npmjs.com/package/babel-plugin-transform-builtin-extend. Le
approximate
option qui est le même comportement de Babel 5. Attention, le non-approximate
comportement est certainement le bord de casey et ne fonctionne pas dans 100% des cas.Error
de créer de nouvelles classes d'exception. AFAICT, cela devrait correspondre à la sous-classement dans l'ES6, sauf si je suis donnant sur quelque chose. J'ai aussi trouvé cet article sur ES6 classe sémantique qui a un exemple exactement de sublassingError
.babel-preset-node5
:Error extracting /Users/arve/.npm/babel-preset-node5/6.1.4/package.tgz archive: ENOENT: no such file or directory, open '/Users/arve/.npm/babel-preset-node5/6.1.4/package.tgz'
.babel-preset-es2015-node5
à la place? Que l'on regarde d'un peu plus solide de toute façon.babel-preset-node5
a été corrigé.Wontfix
tag sur cette question dans phabricator, c'est un peu décevant parce que je pensais que je devrais attendre que cette fonction, au moins si Babel fait correctement et selon les spécifications.var CustomError = function(message){ Error.call(this, message) this.message = message }