2010-11-07 7 views
3

Je fais des trucs de classe comme JavaScript tels queutilisation de la mémoire de classe JavaScript

MyClass = function() 
{ 
    var x; 

    this.sayX = function() 
    { 
     alert(x); 
    } 
} 

mais je l'ai aussi vu

MyClass = function() 
{ 
    this.x = 0; 
} 

MyClass.prototype.sayX = function() 
{ 
    alert(this.x); 
} 

La grande question est, suis-je gaspille encore ou sont-ils capables de voir la duplication dans ma méthode et de les optimiser? La raison pour laquelle je pose la question est parce que je préfère cacher les données et ne pas avoir à tout préfixer absolument avec 'ceci'.

+0

Comme une note, vous pouvez utiliser [avec (ce) {}] (http://javascript.about.com/library/blwith.htm) si elle vous aide . –

+4

NE PAS utiliser "avec". Il est dangereux à utiliser et sera supprimé des futures implémentations d'ECAMScript. Je ne peux pas trop insister sur ce point - il est préférable de prétendre que "avec" n'existe pas en JavaScript. – Hamish

+0

Si vous le faites de la première façon, si vous faites un héritage, vous devrez être beaucoup plus prudent sur ce que vous faites, comment vous mélangez les deux techniques, quand vous appelez le super constructeur, etc. –

Répondre

4

L'empreinte mémoire du premier sera toujours plus grande. Considérez prototype comme un paquet partagé de méthodes que toutes les instances peuvent utiliser. C'est efficace car vous ne créez pas de nouvelle fonction pour chaque instance, mais vous réutilisez la méthode existante déjà en mémoire.

Les bonnes nouvelles sont que les deux manières que vous avez montrées peuvent être combinées. Mais dans la mesure où vous avez affaire à une petite base de code, vous ne devriez pas vous soucier de l'utilisation de la mémoire. Vous pouvez même utiliser des modèles comme

// everything will be created for every 
// instance, but the whole thing is nicely 
// wrapped into one 'factory' function 
myClass = function() { 
    // private variables 
    var x; 

    // private methods 
    function doSomethingWithX() {} 

    // public interface 
    return { 
    sayX: function() { 
     alert(x); 
    }, 
    publicMethod: function() { .. }, 
    // ... 
    }; 
}; 

Remarque, je intentionnellement changé myClass en minuscules, car il est plus une fonction constructeur et il n'y a pas besoin d'utiliser new lors de l'appel!


MISE À JOUR - il y a un troisième motif qui convient bien à vos besoins:

MyClass = function (x, y, whatever) { 
    this._init.apply(this, arguments); 
} 

// The prototype creates a scope for data hiding. 
// It also includes a constructor function. 
MyClass.prototype = (function() { 
    var x; // private 
    return { 
    _init: function (x_in) { 
     x = x_in; 
    }, 
    sayX: function() { 
     alert(x); 
    }, 
    // ... 
    }; 
})(); 
+0

Ceci n'est pas strictement true ("L'empreinte mémoire du premier sera toujours plus grande"). Imaginez qu'il n'y ait qu'un seul objet de ce type en existence à la fois. Bien que vous puissiez peut-être argumenter que le premier cas a un autre contexte d'exécution lié ... mais c'est encore plus fin poils :-) –

+0

Votre commentaire est à peine constructif. S'il n'a besoin que d'une instance d'un objet, il crée un singleton et ne s'inquiète pas de l'empreinte mémoire. – galambalazs

+0

C'est très instructif, mais cela ne répond pas du tout à ma question. Les moteurs JavaScript modernes peuvent-ils optimiser ces frais généraux? Je peux juste construire quelques tests pour le savoir. – RandomInsano