Maison  >  Article  >  interface Web  >  Explication de base orientée objet JS (mode usine, mode constructeur, mode prototype, mode mixte, mode prototype dynamique)_compétences javascript

Explication de base orientée objet JS (mode usine, mode constructeur, mode prototype, mode mixte, mode prototype dynamique)_compétences javascript

WBOY
WBOYoriginal
2016-05-16 16:39:341016parcourir

Qu'est-ce que l'orientation objet ? L'orientation objet est une pensée ! (absurdité).

Orienté objet peut considérer les modules clés du programme comme des objets, et les modules ont des propriétés et des méthodes. De cette façon, si nous encapsulons certaines propriétés et méthodes, cela sera très pratique à utiliser à l'avenir, et nous pourrons également éviter un travail fastidieux et répétitif. Ensuite, j'expliquerai l'implémentation orientée objet dans JS.

Mode usine

Le modèle d'usine est un modèle de conception bien connu dans le domaine du génie logiciel. Étant donné que les classes ne peuvent pas être créées dans ECMAScript, l'encapsulation de fonctions est utilisée pour créer des objets avec des interfaces spécifiques. La méthode d'implémentation est très simple, c'est-à-dire créer un objet dans la fonction, attribuer des propriétés et des méthodes à l'objet, puis renvoyer l'objet.

function createBlog(name, url) {
  var o = new Object();
  o.name = name;
  o.url = url;
  o.sayUrl= function() {
    alert(this.url);
  }
  return o;
}

var blog1 = createBlog('wuyuchang', 'http://www.jb51.net/');

Vous pouvez voir que la méthode d'implémentation du modèle d'usine est très simple, ce qui résout le problème de la création de plusieurs objets similaires. Cependant, le modèle d'usine ne peut pas identifier le type d'objets car ce sont tous des objets, contrairement à Date, Array, etc., il existe donc un modèle de constructeur.

 Modèle de constructeur

Les constructeurs dans ECMAScript peuvent créer des objets de types spécifiques, similaires aux objets JS natifs tels que Array et Date. La méthode de mise en œuvre est la suivante :

function Blog(name, url) {
  this.name = name;
  this.url = url;
  this.alertUrl = function() {
    alert(this.url);
  }
}

var blog = new Blog('wuyuchang', 'http://www.jb51.net/');
console.log(blog instanceof Blog);  // true, 判断blog是否是Blog的实例,即解决了工厂模式中不能

À l'exception des noms de fonctions différents entre cet exemple et le modèle d'usine, les enfants attentifs devraient trouver de nombreuses différences :

La première lettre du nom de la fonction doit être en majuscule (Bien que la norme n'exige pas strictement que la première lettre soit en majuscule, par convention, la première lettre du constructeur doit être en majuscule
Aucun objet créé affiché
Attribuez directement des propriétés et des méthodes à cet objet
Pas de déclaration de retour
Utilisez new pour créer des objets
Capable de reconnaître des objets (c'est là que le modèle constructeur est meilleur que le modèle usine)

Bien que le constructeur soit facile à utiliser, il n'est pas sans défauts. Le plus gros problème avec l'utilisation du constructeur est que la méthode doit être recréée à chaque fois qu'une instance est créée (en théorie, les propriétés de l'objet sont différent à chaque fois qu'un objet est créé. Les méthodes de l'objet sont les mêmes), mais il n'est pas nécessaire de créer exactement la même méthode deux fois, on peut donc déplacer la fonction en dehors de l'objet (peut-être que certains enfants ont déjà vu les défauts, huer!).

function Blog(name, url) {
  this.name = name;
  this.url = url;
  this.alertUrl = alertUrl;
}

function alertUrl() {
  alert(this.url);
}

var blog = new Blog('scjb51', 'http://sc.jb51.net/'),
  blog2 = new Blog('jb51', 'http://www.jb51.net/');
blog.alertUrl();  // http://sc.jb51.net/
blog2.alertUrl();  // http://www.jb51.net/

Nous définissons alertUrl comme fonction globale, afin que blog et blog2 accèdent à la même fonction. Mais le problème revient, nous définissons une fonction dans la portée globale qui n'est en fait utilisée que par Blog. Ce qui est quelque peu digne de son nom, ce qui est encore plus inacceptable, c'est que de nombreuses méthodes sont définies dans la portée globale et ne sont utilisées que par des objets spécifiques. Sans parler du gaspillage d'espace, cela perd évidemment l'encapsulation orientée objet, ce qui peut donc être résolu via des prototypes. . question.

 Mode prototype

Chaque fonction que nous créons a un attribut prototype, qui est un pointeur vers un objet, et le but de cet objet est de contenir des propriétés et des méthodes qui peuvent être partagées par toutes les instances d'un type spécifique. L'avantage d'utiliser un objet prototype est que toutes les instances d'objet peuvent partager les propriétés et les méthodes qu'il contient.

function Blog() {
}

Blog.prototype.name = 'wuyuchang';
Blog.prototype.url = 'http://tools.jb51.net/';
Blog.prototype.friend = ['fr1', 'fr2', 'fr3', 'fr4'];
Blog.prototype.alertInfo = function() {
  alert(this.name + this.url + this.friend );
}

// 以下为测试代码
var blog = new Blog(),
  blog2 = new Blog();
blog.alertInfo();  // wuyuchanghttp://tools.jb51.net/fr1,fr2,fr3,fr4
blog2.alertInfo();  // wuyuchanghttp://tools.jb51.net/fr1,fr2,fr3,fr4

blog.name = 'wyc1';
blog.url = 'http://***.com';
blog.friend.pop();
blog2.name = 'wyc2';
blog2.url = 'http://+++.com';
blog.alertInfo();  // wyc1http://***.comfr1,fr2,fr3
blog2.alertInfo();  // wyc2http://+++.comfr1,fr2,fr3

Le modèle de prototype n'est pas sans défauts. Tout d'abord, il omet le constructeur de transmettre les paramètres d'initialisation. Par conséquent, toutes les instances obtiennent les mêmes valeurs d'attribut par défaut. n'est toujours pas un prototype. Le plus gros problème, le plus gros problème avec le modèle de prototype est causé par la nature du partage, si une instance modifie la référence, l'autre change également la référence. Par conséquent, nous n'utilisons généralement pas de prototypes seuls, mais combinons un modèle de prototype et un modèle de constructeur.

 Mode mixte (mode prototype, mode constructeur)

function Blog(name, url, friend) {
  this.name = name;
  this.url = url;
  this.friend = friend;
}

Blog.prototype.alertInfo = function() {
  alert(this.name + this.url + this.friend);
}

var blog = new Blog('wuyuchang', 'http://tools.jb51.net/', ['fr1', 'fr2', 'fr3']),
  blog2 = new Blog('wyc', 'http://**.com', ['a', 'b']);

blog.friend.pop();
blog.alertInfo();  // wuyuchanghttp://tools.jb51.net/fr1,fr2
blog2.alertInfo();  // wychttp://**.coma,b

En mode mixte, le mode constructeur est utilisé pour définir les propriétés de l'instance, tandis que le mode prototype est utilisé pour définir les méthodes et les propriétés partagées. Chaque instance aura ses propres attributs d'instance, mais partagera en même temps des méthodes, économisant ainsi la mémoire au maximum. De plus, ce mode prend également en charge la transmission des paramètres initiaux. Les avantages sont nombreux. Ce mode est la méthode la plus largement utilisée et reconnue pour créer des objets personnalisés dans ECMAScript.

 Mode prototype dynamique

Le mode prototype dynamique encapsule toutes les informations dans le constructeur, et en initialisant le prototype dans le constructeur (seul le prototype est initialisé lorsque le premier objet est instancié), vous pouvez choisir d'initialiser le prototype en jugeant si la méthode est valide. .

function Blog(name, url) {
  this.name = name;
  this.url = url;

  if (typeof this.alertInfo != 'function') {
    // 这段代码只执行了一次
    alert('exe time');
    Blog.prototype.alertInfo = function() {
      alert(thia.name + this.url);
    }
  }
}

var blog = new Blog('wuyuchang', 'http://tools.jb51.net'),
  blog2 = new Blog('wyc', 'http:***.com');

Vous pouvez voir que dans l'exemple ci-dessus, la fenêtre n'apparaît qu'une seule fois, 'exe time', c'est-à-dire lorsque le blog est initialisé. De cette façon, blog2 n'a plus besoin d'initialiser le prototype, c'est parfait pour. créer des objets en utilisant ce mode.

Ce billet de blog fait référence à la 3ème édition de "Programmation avancée avec JavaScript ", mais le langage a été simplifié et les exemples ont été réécrits. S'il y a quelque chose que vous ne comprenez pas, veuillez partir. une réponse et l'auteur mettra à jour le blog.

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn