Encapsulation en JavaScript
L'encapsulation signifie simplement que le monde extérieur ne peut accéder qu'aux variables et fonctions communes de l'objet, masquant les détails et les données.
Il existe trois façons de créer des objets en js, à savoir ouvrir la porte, utiliser des conventions de dénomination pour distinguer les variables privées et fermer pour créer de véritables variables privées.
1. La porte ouverte est la méthode la plus élémentaire pour réaliser des objets. Toutes les méthodes et variables sont communes et accessibles au monde extérieur.
var Book = function(name){ if(this.check(name)){ console.log("error"); throw new Error("name null"); } this.name = name; } Book.prototype = { check:function(name){ if(!name){ return true; } }, getName:function(){ return this.name; } } var book = new Book("哈哈"); //output:哈哈 哈哈 console.log(book.name,book.getName());
Cet exemple est un exemple typique de porte ouverte, où le monde extérieur peut accéder directement aux propriétés et méthodes de l'objet. Vous pouvez remarquer que les propriétés et les variables sont créées avec "this".
2. Utilisez des conventions de dénomination pour distinguer les variables privées. Cette méthode est une version optimisée de la méthode de la porte ouverte. Elle se distingue simplement par "_" devant les variables ou méthodes privées si un programmeur a l'intention d'utiliser la méthode _getName(). appeler la méthode ne peut toujours pas être empêché, cela ne cache pas vraiment les variables.
3. La fermeture crée de vraies variables privées.Cette méthode profite du fait que seules les fonctions dans js ont une portée et définit les variables pertinentes dans la portée du constructeur. Ces variables sont accessibles par toutes les fonctions dans la portée du domaine de définition.
var Book2 = function(name){ if(check(name)){ console.log("error"); throw new Error("name null"); } name = name; function check(name){ if(!name){ return true; } } this.getName = function(){ return name; } } Book2.prototype = { display:function(){ //无法直接访问name return "display:"+this.getName(); } } var book2 = new Book2("哈哈"); //output:undefined "哈哈" "display:哈哈" console.log(book2.name,book2.getName(),book2.display());
Comme vous pouvez le voir, dans cet exemple, accéder directement au nom renverra des résultats non définis. Vous pouvez voir la différence entre cet exemple et le type porte ouverte. Les variables du type porte ouverte sont créées en utilisant "this", tandis que dans cet exemple, var est utilisé pour les créer. de sorte que les fonctions name et check ne peuvent être créées que dans le constructeur. Elles sont accessibles dans le cadre de la fonction et ne sont pas directement accessibles par le monde extérieur.
Cette méthode résout les problèmes des deux premières méthodes, mais elle présente également certains inconvénients. En mode de création d'objet à porte ouverte, toutes les méthodes sont créées dans l'objet prototype, donc quel que soit le nombre d'instances d'objet générées, une seule copie de ces méthodes existe dans la mémoire. Avec cette méthode, chaque nouvel objet généré sera Créer. une nouvelle copie des variables et méthodes privées, qui consomme plus de mémoire.
Héritage en JavaScript
Cours de base de livre :
var Book = function(name){ if(this.check(name)){ console.log("error"); throw new Error("name null"); } this.name = name; } Book.prototype = { check:function(name){ if(!name){ return true; } }, getName:function(){ return this.name; } }
Méthode héritée :
function extend(subClz,superClz){ var F = function(){} F.prototype = superClz.prototype; subClz.prototype = new F(); subClz.prototype.constructor = subClz; subClz.superClass = superClz.prototype; if(superClz.prototype.constructor == Object.prototype.constructor){ superClz.prototype.constructor = superClz; }
L'utilisation d'une fonction F vide comme pont peut éviter la surcharge supplémentaire liée à l'appel du constructeur de la classe parent lors de l'instanciation directe de la classe parent. De plus, lorsque le constructeur de la classe parent a des paramètres, vous souhaitez l'implémenter directement via subClass.prototype = new superClass(). ; L'appel du constructeur de la classe parent et l'héritage via la chaîne de prototypes ne sont pas autorisés.
subClz.superClass = superClz.prototype; if(superClz.prototype.constructor == Object.prototype.constructor){ superClz.prototype.constructor = superClz; }
L'ajout de ces trois phrases peut empêcher la sous-classe d'hériter de la classe parent et d'écrire Book.call(this, name); à la place, écrivez simplement ArtBook.superClass.Constructor.call(this, name);
Et lorsque la sous-classe remplace la méthode de la classe parent, elle peut appeler la méthode de la classe parent :
ArtBook.prototype.getName = functiion(){ return ArtBook.superClass.getName.call(this) + "!!!"; }
Sous-classe ArtBook :
var ArtBook = function(name,price){ ArtBook.superClass.Constructor.call(this,name); this.price = price; } extend(ArtBook,Book); ArtBook.prototype.getPrice = function(){ return this.price; } ArtBook.prototype.getName = function(){ return ArtBook.superClass.getName.call(this)+"!!!"; }