Question

Je suis en train d'utiliser certaines des fonctionnalités OO plus avancés de Javascript, suivant le modèle « super constructeur » de Doug Crawford. Cependant, je ne sais pas comment définir et obtenir les types de mes objets en utilisant le système de type natif de Javascript. Voici comment je l'ai maintenant:

function createBicycle(tires) {
    var that = {};
    that.tires = tires;
    that.toString = function () {
        return 'Bicycle with ' + tires + ' tires.';
    }
}

Comment puis-je définir ou récupérer le type de mon nouvel objet? Je ne veux pas créer un attribut type s'il y a une bonne façon de le faire.

Est-il possible de passer outre les opérateurs de typeof ou instanceof pour mon objet personnalisé?

Était-ce utile?

La solution

L'opérateur instanceof , en interne, après que les deux valeurs d'opérandes sont rassembler, utilise l'opération abstraite [[HasInstance]](V) , qui repose sur la chaîne prototype .

Le modèle que vous avez affichée, consiste simplement à augmenter les objets, et la chaîne prototype ne sert pas du tout.

Si vous voulez vraiment utiliser l'opérateur instanceof, vous pouvez combiner la technique d'un autre Crockford, prototypal héritage avec super constructeurs , essentiellement à hériter de la Bicycle.prototype, même si elle est un objet vide, pour tromper instanceof:

// helper function
var createObject = function (o) {
  function F() {}
  F.prototype = o;
  return new F();
};

function Bicycle(tires) {
    var that = createObject(Bicycle.prototype); // inherit from Bicycle.prototype
    that.tires = tires;                         // in this case an empty object
    that.toString = function () {
      return 'Bicycle with ' + that.tires + ' tires.';
    };

    return that;
}

var bicycle1 = Bicycle(2);

bicycle1 instanceof Bicycle; // true

A plus approfondi article:

Autres conseils

Si vous déclarez Bicycle comme ça, instanceof fonctionnera:

function Bicycle(tires) {
  this.tires = tires;
  this.toString = function () {
    return 'Bicycle with ' + tires + ' tires.';
  }
}

var b = new Bicycle(2);
console.log(b instanceof Bicycle);

si vous utilisez un constructeur, une meilleure solution que instanceOf, serait ceci:

Object.toType = function(obj) {
  return ({}).toString.call(obj).match(/\s([a-z|A-Z]+)/)[1].toLowerCase();
}


toType({a: 4}); //"object"
toType([1, 2, 3]); //"array"
(function() {console.log(toType(arguments))})(); //arguments
toType(new ReferenceError); //"error"
toType(new Date); //"date"
toType(/a-z/); //"regexp"
toType(Math); //"math"
toType(JSON); //"json"
toType(new Number(4)); //"number"
toType(new String("abc")); //"string"
toType(new Boolean(true)); //"boolean"
toType(new CreateBicycle(2)); //"createbicycle"

L'explication de POURQUOI c'est la meilleure façon de le faire dépend dans Ce poste .

Dans Firefox uniquement, vous pouvez utiliser la propriété __proto__ pour remplacer le prototype d'un objet. Dans le cas contraire, vous ne pouvez pas changer le type d'un objet qui a déjà été créé, vous devez créer un nouvel objet en utilisant le mot-clé new.

  

A mon avis, dans un bien conçu   Type heirarchy, vous n'avez pas besoin de savoir   les types des objets individuels.   Mais il me semble être dans la minorité   ce point.

     

Si vous devez avoir une identification de type,   rendre explicite.

     

MyClass.prototype.type = "MyClass";

     

Il est fiable et portable, au moins   pour vos objets. Il travaille également à travers   contextes. objets DOM sont une autre   la matière, bien que vous pouvez faire des choses   plus facile pour vous-même avec

     

window.type = "fenêtre";

     

et ainsi de suite.

Je crois que la citation ci-dessus a été écrit par Douglas Crockford .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top