Maison > interface Web > js tutoriel > Résumé des modèles de création d'objets dans les astuces JavaScript_javascript

Résumé des modèles de création d'objets dans les astuces JavaScript_javascript

WBOY
Libérer: 2016-05-16 15:04:47
original
1139 Les gens l'ont consulté

Résumé des modèles de création d'objets en JavaScript

**Mode objet de création JavaScript :

Objet littéral
Mode usine
Modèle de constructeur
Mode prototype
Combiner des modèles de constructeur et de prototype
Mode dynamique prototype
**

La plupart des langages orientés objet ont le concept de classe, à travers laquelle plusieurs objets avec les mêmes méthodes et propriétés peuvent être créés. Bien que techniquement parlant, JavaScript soit un langage orienté objet, JavaScript n'a pas la notion de classes, tout est objet. Tout objet est une instance d'un certain type de référence, qui est créée via un type de référence existant ; le type de référence peut être natif ou personnalisé.

1. Objet littéral

var person = {
    name : 'Nicholas';
    age : '22';
    job :"software Engineer"
    sayName: function() {
      alter(this.name);
  }
}
Copier après la connexion

Dans l'exemple, un objet nommé personne est créé et trois attributs (nom, âge, travail) et une méthode (sayName()) y sont ajoutés. La méthode sayName() est utilisée pour afficher this.name( est. analysée comme la valeur de person.name).

Les littéraux d'objet peuvent être utilisés pour créer un seul objet, mais cette méthode présente un inconvénient évident : créer de nombreux objets en utilisant la même interface produira beaucoup de code en double.

2. Mode usine

Le modèle d'usine est un modèle de conception bien connu dans le domaine du génie logiciel. Le modèle d'usine résume le processus de création d'objets spécifiques et utilise des fonctions pour encapsuler les détails de la création d'objets avec une interface spécifique.

function createPerson(name,age,job){
  var o = new object{};
  o.name=name;
  o.age=age;
  o.job=job;
  o.sayName=function(){
    alert(this.name);
  };
  return o;
}
var person1=creatPerson("Nicholas",22,"software Engineer");
var person2=creatPerson("Greg",24,"student");
Copier après la connexion

La fonction creatPerson{} peut construire un objet Person contenant toutes les informations nécessaires en fonction des paramètres acceptés. Cette fonction peut être appelée un nombre incalculable de fois, et à chaque fois elle renverra un objet contenant trois propriétés et une méthode.

Bien que le modèle d'usine résolve le problème de la création de plusieurs objets similaires, il ne résout pas le problème de la reconnaissance des objets (c'est-à-dire comment connaître le type d'un objet).

3. Modèle de constructeur

function Person(name,age,job) {
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayName = function() {
    alert(this.name);
  }
}
//通过new操作符创建Person的实例
var person1 = new Person("Nicholas",22,"software Engineer");
var person2 = new Person("Greg",24,"student");
person1.sayName(); //Nicholas
person2.sayName(); //Greg
Copier après la connexion

La différence avec le mode usine est

Aucun objet créé affiché

Attribuer des propriétés et des méthodes directement à cet objet

Aucune déclaration de retour

Pour créer une nouvelle instance de Person, vous devez utiliser l'opérateur new. 4 étapes pour appeler le constructeur :

Créer un nouvel objet

Attribuez la portée du constructeur au nouvel objet (cela pointe vers ce nouvel objet)

Exécuter le code dans le constructeur

Renvoyer le nouvel objet

Tous les objets créés dans cet exemple sont à la fois des instances d'objet et des instances de personne. Peut être vérifié via l’opérateur instanceof.

alert(person1 instanceof Object);//true
Copier après la connexion

Le modèle constructeur a aussi ses propres problèmes. En fait, la méthode sayName sera recréée une fois sur chaque instance. Il convient de noter que les méthodes créées par instanciation ne sont pas égales, comme peut le prouver le code suivant

alert(person1.sayName == person2.sayName);//false
Copier après la connexion

Ce problème peut être résolu en déplaçant la méthode en dehors du constructeur en tant que fonction globale.

function Person(name,age,job) {
  this.name = name;
  this.age = age;
  this.job = job;  
}
function sayName() {
    alert(this.name);
  }
Copier après la connexion

Les fonctions globales créées lors de la globalisation ne peuvent en fait être appelées que par des instances créées via Person, ce qui est un peu mal nommé ; si l'objet doit définir de nombreuses méthodes, alors de nombreuses fonctions globales doivent être définies, sans encapsulation.

4. Mode prototype

Chaque fonction créée en JavaScript possède un attribut prototype, qui est un pointeur vers un objet qui contient des propriétés et des méthodes qui peuvent être partagées par toutes les instances d'un type spécifique (laissez toutes les instances d'objet partager ses propriétés et méthodes)

function Person() {}
  Person.prototype.name ="Nicholas";
  Person.prototype.age = 22;
  Person.prototype.job = "software Engineer";  
  Person.prototype.sayName(){
    alert(this.name);
  };
 var person1 = new Person();
 person1.sayName(); //Nicholas
alert(person1.sayName == person2.sayName);//true
Copier après la connexion

以上代码做了这几件事情:

定义了一个构造函数Person,Person函数自动获得一个prototype属性,该属性默认只包含一个指向Person的constructor属性
通过Person.prototype添加三个属性,和一个方法

创建一个Person的实例,随后在实例上调用了sayName()方法

Résumé des modèles de création dobjets dans les astuces JavaScript_javascript

Résumé des modèles de création dobjets dans les astuces JavaScript_javascript

Résumé des modèles de création dobjets dans les astuces JavaScript_javascript

图中展示了Person构造函数、Person的原型属性以及Person的两个实例,之间的关系。Person.prototype指向了原型对象,Person.prototype.constructor有指回了Person。原型对象中除了包含constructor属性,还包含后来添加的其他属性和方法,Person的两个实例person1和person2都包含一个内部属性,该属性仅指向Person.prototype。

sayName()方法的调用过程:

在person1实例上查找logName()方法,发现没有这个方法,于是追溯到person1的原型

在person1的原型上查找sayame()方法,有这个方法,于是调用该方法

基于这样一个查找过程,我们可以通过在实例上定义原型中的同名属性,来阻止该实例访问原型上的同名属性,需要注意的是,这样做并不会删除原型上的同名属性,仅仅是阻止实例访问。

function Person() {}
  Person.prototype.name ="Nicholas";
  Person.prototype.age = 22;
  Person.prototype.job = "software Engineer";  
  Person.prototype.sayName(){
    alert(this.name);
  };
 var person1 = new Person();
 var person2 = new Person();
 person1.name="Greg"
alert(person1.name) //Greg 来自实例
alert(person2.name) //Nicholas 来自原型
Copier après la connexion

使用delete操作符可以完全删除实例属性

delete person1.name;
alert(person1.name) //Nicholas 来自原型
Copier après la connexion

使用hasOwnProperty()方法可以检测一个属性是存在于实例还是原型中

function Person() {}
  Person.prototype.name ="Nicholas";
  Person.prototype.age = 22;
  Person.prototype.job = "software Engineer";  
  Person.prototype.sayName(){
    alert(this.name);
  };
 var person1 = new Person();
 var person2 = new Person();
 alert(person1,hasOwnProperty("name"));//false
 person1.name="Greg"
alert(person1.name) //Greg 来自实例
 alert(person1,hasOwnProperty("name"));//true
alert(person2.name) //Nicholas 来自原型
 alert(person2,hasOwnProperty("name"));//false
 delete person1.name;
alert(person1.name) //Nicholas 来自原型
 alert(person1,hasOwnProperty("name"));//false
Copier après la connexion

下图展示了在不同情况下实例与原型之间的关系

Résumé des modèles de création dobjets dans les astuces JavaScript_javascript

简单的原型语法

function Person() {}
 Person.prototype={
 name :"Nicholas",
 age : 22,
 job : "software Engineer", 
 sayName:function(){
    alert(this.name);
    }
  };
Copier après la connexion

在上面的代码中constructor属性不再指向Person了,通过constructor无法确定对象的类型了。可以像下面这样特意将他设置回适当的值

function Person() {}
 Person.prototype={
 constructor:Person,
 name :"Nicholas",
 age : 22,
 job : "software Engineer",  
 sayName:function(){
    alert(this.name);
    }
  };
Copier après la connexion

重设constructor属性会导致它的[[Enumerable]]特性被设置为true,默认情况,原生的constructor属性是不可枚举的,可以使用Object.defineProperty()方法来改变

Object.defineProperty(Person.prototype,"constructor",{
  enumerable:false,
  value:Person
});
Copier après la connexion

原型中查找值的过程是一次搜索,原型对象所做的任何修改都能从实例上立即反应出来

var friend=new Person();
Person.prototype.sayHi=function(){
  alert("hi);
}
friend,sayHi();//"hi"(没有问题)
Copier après la connexion

person实例是在添加新方法之前创建的,但仍可以访问新添加的方法,原因是实例与原型之间的松散连接关系
重写原型对象后的情况

function Person() {}
var friend=new Person();
 Person.prototype={
 name :"Nicholas",
 age : 22,
 job : "software Engineer", 
 sayName:function(){
    alert(this.name);
    }
  };
  friend.sayName();//error
Copier après la connexion

调用friend.sayName()时发生错误的原因是,friend指向的原型中不包含以该字段命名的属性,如下图。

Résumé des modèles de création dobjets dans les astuces JavaScript_javascript

原型对象的问题

原型对象省略了为构造函数传递初始化参数这一环节,所有势力在默认情况下都取得相同的属性值。原型模型最大的问题是有其共享本性所导致的。当原型模型包含引用类型的属性来说,问题就比较严重了。来看下面的例子。

function Person() {}
 Person.prototype={
 constructor:Person,
 name :"Nicholas",
 age : 22,
 job : "software Engineer",  
 friends:["Shelby","Court"],
 sayName:function(){
    alert(this.name);
    }
  };
  var person1=new Person();
  var person2=new Person();
  person1.friend.push("Van");
  alert(person1.friends);//"Shelby,Court,Van"
  alert(person2.friends);//"Shelby,Court,Van"
 alert(person1.friends==person2.friends);//true
Copier après la connexion

5、组合使用构造函数模式和原型模式

组合使用构造函数模式和原型模式中,构造函数用于定义实例属性,原型模型用于定义方法和共享的属性。这样每个实例都会有自己的一份实例属性的副本,同时也可以共享对方法的引用,最大限度的节省了内存。

function Person(name,age,job) {
  this.name = name;
  this.age = age;
  this.job = job;  
  this.friends=["Shelby","Court"];
}
Person.prototype={
 constructor:Person,
 sayName:function(){
    alert(this.name);
    }
  }
var person1=new Person("Nicholas",22,"software Engineer");
var person2 = new Person("Greg",24,"student");
person1.friend.push("Van");
  alert(person1.friends);//"Shelby,Court,Van"
  alert(person2.friends);//"Shelby,Court"
 alert(person1.friends==person2.friends);//false
 alert(person1.sayName==person2.sayName);//true
Copier après la connexion

6、动态原型模式

原型动态模式将需要的所有信息都封装到构造函数中,通过if语句判断原型中的某个属性是否存在,若不存在(在第一次调用这个构造函数的时候),执行if语句内部的原型初始化代码。

function Person(name,age) {
  this.name = name;
  this.age = age;
  this.job =job;
//方法
  if(typeof this.sayName != 'function') {
  Person.prototype.sayName = function() {
      alert(this.name);
    };   
  }
}
var friend = new Person('Nicholas','22','Software Engineer');//初次调用构造函数,此时修改了原型
var person2 = new Person('amy','21');//此时sayName()方法已经存在,不会再修改原型
Copier après la connexion

Lecture recommandée :

Manières courantes orientées objet JS pour créer des objets (mode usine, mode constructeur, mode prototype)

Ce qui précède est le mode de création d'objets en JavaScript introduit par l'éditeur. J'espère qu'il vous sera utile !

source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal