10
votes

Comment fonctionne exactement de l'instance JavaScript? Est-ce le style lent?

Comment la performance de instanceOf Fair pour "énormes bibliothèques"?

Voyage-t-il la chaîne prototype une par une , semblable à ceci? : xxx

est instanceof relativement dénonfomant puis, comparé au stockage d'un numéro d'identification d'interface unique dans la propriété de chaque objet.


1 commentaires

3 Réponses :


12
votes

Ouais quelque chose comme ça. Voici la partie pertinente du Spécification :

11.8.6 L'instance de l'opérateur strong> p>

La production relationnelexpression em>: relationnelexpression em> instance de stry> shiftexpression em> est évaluée comme suit: p>

  1. laissez lref em> résultat de l'évaluation de relanceXpression em>. li>
  2. laisse lval em> getvalue ( lref em>). li>
  3. laissez rref em> résultat de l'évaluation Shiftexpression em>. li>
  4. laissez rval em> getvalue ( rref em>). li>
  5. Si type ( rval em>) n'est pas objet, jetez une exception forte> TypeError forte>. Li>
  6. si rval em> n'a pas de méthode interne [[hasintstance]], jette une exception typeError forte>. li>
  7. renvoie le résultat de l'appelant la méthode interne [[Hasinstance]] de rval em> avec argument lval em>. li> ol> blockquote>

    appeler la méthode [[hasinstance]]] em> est définie comme p>

    15.3.5.3 [[HASInstance]] (v) strong>

    suppose f em> est un objet de fonction. P>

    lorsque la méthode interne [[HASINSTIC]] de f em> est appelée de valeur v em>, les étapes suivantes sont prises: p>

    1. Si v em> n'est pas un objet, retour faux fort>. li>
    2. laissez o em> résultat de l'appelant la méthode interne [[get]] de f em> avec nom de propriété " prototype fort>". li>
    3. Si le type ( o em>) n'est pas un objet, lancez une exception forte> TypeError forte>. Li>
    4. répéter
      une. Laissez v em> la valeur de la propriété interne [[prototype]] de v em>.
      b. Si v em> est null fort>, retour faux fort>.
      c. Si o em> et v em> reportez-vous au même objet, renvoyez vrai fort>. Li> ol> blockQuote>

      En ce qui concerne la performance: cela dépend probablement des implémentations réelles dans les navigateurs. Il peut y avoir d'énormes différences entre eux afin que la meilleure chose soit de faire des points de repère, par ex. avec http://jsperf.com/ . p>


      Un problème avec instance de code> Est-ce que cela pourrait ne pas fonctionner si vous l'invoquez sur des éléments de différents contextes, tels qu'un cadre ou une iframe. Par exemple, laisse A code> être un objet que vous pouvez accéder via iframe.contentwindow.a code> et que vous souhaitez tester s'il s'agit d'une matrice, puis p>

      iframe.contentWindow.a instanceof Array
      


2 commentaires

Ce n'est pas un problème, c'est un avantage énorme! :) Vous pouvez déconner avec iframe.contentwindow.array.pototype , puis avoir des tableaux "spéciaux"! Ou .Object.Prototype :)


@Cwolves: qui pourrait avoir un comportement inattendu dans l'iframe. C'est un problème si on ne sait pas à ce sujet.



12
votes

en V8 (moteur JS de Chrome), il semble y avoir peu de performances de performance:

> var classes = [];
> for(var i=0; i<10000; i++){
>   classes[i] = function(){};
>   i && (classes[i].prototype = new (classes[i-1])());
> }
>
> var obj0 = new classes[0],
>  obj9999 = new classes[9999];
>
> var start = (+new Date()); for(var i=0; i<10000000; i++){ obj0   instanceof classes[0] } console.log((+new Date()) - start);
138
> var start = (+new Date()); for(var i=0; i<10000000; i++){ obj999 instanceof classes[0] } console.log((+new Date()) - start);
138


1 commentaires

passer un peu fou est exactement ce qu'il faut parfois



7
votes

Selon ce que Felix Kling a cité, tout ce cas d'instanceOf (à l'exclusion des contrôles d'erreur) est de vérifier si la propriété prototype (qui doit être un objet) de la fonction peut être trouvée quelque part sur la chaîne de prototype xxx Pre>

Voici quelques pseudocodes: P>

person instanceof Person
//ROUGHTLY equals
person.instanceOf(Person)

person.instanceOf = function(Person) {
    if(typeof Person!='object') throw new TypeError;
    if(!([[HasInstance]] in Person)) throw new TypeError;
    return Person.[[HasInstance]](this /* person */)
}


Person.[[HasInstance]] = function(V) {
    if(typeof V!='object') return false;
    var O = this.prototype;
    if(typeof O!='object') throw new TypeError;
    while(true) {
        V = V.__proto__; // [[prototype]] (hidden) property
        if(V==null) return false;
        if(V==O) return true;
    }
}


0 commentaires