Maison  >  Article  >  interface Web  >  Explication détaillée de la création d'objets basés sur JavaScript orienté objet

Explication détaillée de la création d'objets basés sur JavaScript orienté objet

PHPz
PHPzoriginal
2016-05-16 15:26:231360parcourir

Chaque fonction que nous créons possède un attribut prototype, qui est un objet dont le but 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. Logiquement, cela peut être compris de cette façon : le prototype est l'objet prototype de l'objet créé à l'aide du constructeur. L’avantage d’utiliser un prototype est que toutes les instances d’objet peuvent partager les propriétés et méthodes qu’il contient. En d'autres termes, vous n'avez pas besoin de définir les informations sur l'objet dans le constructeur, mais ajoutez ces informations directement au prototype

La méthode prototype utilise l'attribut prototype de l'objet, qui peut être considéré comme la méthode utilisée pour créer un nouvel objet dépendant. Ici, utilisez d’abord un constructeur vide pour définir le nom de la fonction. Ensuite, toutes les propriétés et méthodes sont affectées directement à l’attribut prototype. J'ai réécrit l'exemple précédent et le code est le suivant :

function Car() { }; 
//将所有的属性的方法都赋予prototype属性 
Car.prototype.color = "blue"; 
Car.prototype.doors = 4; 
Car.prototype.mpg = 25; 
Car.prototype.showColor = function() { 
  return this.color; 
}; 
var Car1 = new Car(); 
var Car2 = new Car(); 
document.write(Car1.showColor()+"
");//输出:blue 
document.write(Car2.showColor());//输出:blue

Dans ce code, définissez d'abord le constructeur Car() sans aucun code. Les lignes de code suivantes définissent les propriétés de l'objet Car en ajoutant des propriétés à la propriété prototype de la voiture. Lorsque new Car() est appelée, toutes les propriétés du prototype sont immédiatement affectées à l'objet à créer, ce qui signifie que toutes les instances de Car stockent des pointeurs vers la fonction showColor(). Sémantiquement parlant, toutes les propriétés semblent appartenir à un seul objet, résolvant ainsi les problèmes de la méthode de fabrique et de la méthode constructeur précédentes

De plus, en utilisant cette méthode, vous pouvez également utiliser l'opérateur instanceof Vérifiez le type d'objet pointé par une variable donnée :

Le code est le suivant :
document.write(Car1 instanceof Car);    //输出:tru

L'approche prototype semble être une bonne solution. Malheureusement, ce n’est pas si satisfaisant. Premièrement, ce constructeur n'a aucun paramètre. En utilisant la méthode prototype, vous ne pouvez pas initialiser les valeurs d'attribut en passant des paramètres au constructeur, car l'attribut de couleur de Car1 et Car2 est égal à "bleu", l'attribut de portes est égal à 4 et l'attribut mpg est égal à 25. Cela signifie que vous devez modifier la valeur par défaut d'une propriété après la création de l'objet, ce qui est ennuyeux, mais ce n'est pas tout. Le vrai problème survient lorsque les propriétés pointent vers des objets plutôt que vers des fonctions. Le partage de fonctions ne pose pas de problèmes, mais les objets sont rarement partagés entre plusieurs instances. Veuillez considérer l'exemple suivant :

function Car() { };//定义一个空构造函数,且不能传递参数 
Car.prototype.color = "blue"; 
Car.prototype.doors = 4; 
Car.prototype.mpg = 25; 
Car.prototype.drivers = new Array("Mike","John"); 
Car.prototype.showColor = function() { 
  return this.color; 
}; 
var Car1 = new Car(); 
var Car2 = new Car(); 
Car1.drivers.push("Bill"); 
document.write(Car1.drivers+"
");//输出:Mike,John,Bill 
document.write(Car2.drivers);//输出 :Mike,John,Bill

Dans le code ci-dessus, l'attribut drivers est un pointeur vers un objet Array contenant les deux noms "Mike" et "John". Puisque les pilotes sont des valeurs de référence, les deux instances de Car pointent vers le même tableau. Cela signifie ajouter la valeur « Bill » à Car1.drivers, qui est également visible dans Car2.drivers. La sortie de l'un ou l'autre de ces pointeurs entraîne l'affichage de la chaîne "Mike,John,Bill". Puisqu’il y a tellement de problèmes lors de la création d’objets, vous devez vous demander : existe-t-il un moyen raisonnable de créer des objets ? La réponse est oui, vous devez utiliser une combinaison de méthodes de constructeur et de prototype

méthode mixte constructeur/prototype (il est recommandé d'utiliser

En mélangeant la méthode constructeur et la méthode prototype, vous pouvez créer des objets comme les autres langages de programmation. Le concept est très simple, c'est-à-dire utiliser le constructeur pour définir toutes les propriétés non fonctionnelles de l'objet, et utiliser. la méthode prototype pour définir les propriétés fonctionnelles de l'objet (méthode). Le résultat est que toutes les fonctions ne sont créées qu'une seule fois, et chaque objet a sa propre instance de propriété d'objet. Nous réécrivons l'exemple précédent comme suit :

.
function Car(Color,Doors,Mpg) { 
 this.color = Color; 
 this.doors = Doors; 
 this.mpg = Mpg; 
 this.drivers = new Array("Mike","John"); 
}; 
Car.prototype.showColor = function() { 
   return this.color; 
}; 
var Car1 = new Car("red",4,23); 
var Car2 = new Car("blue",3,25); 
Car1.drivers.push("Bill"); 
document.write(Car1.drivers+"
");//输出:Mike,John,Bill 
documnet.write(Car2.drivers);//输出:Mike,John

Maintenant, cela ressemble plus à la création d'un objet normal. Toutes les propriétés non fonctionnelles sont créées dans le constructeur, ce qui signifie que les propriétés peuvent se voir attribuer des valeurs par défaut en utilisant les paramètres du constructeur. constructeur car une seule instance de la fonction showColor() est créée, il n'y a donc pas de gaspillage de mémoire. De plus, l'ajout de la valeur "Bill" au tableau des pilotes de Car1 n'affectera pas le tableau de Car2, donc lors de la sortie des valeurs de ceux-ci. tableaux, Car1.drivers affiche "Mike, John, Bill" et Car2.drivers affiche "Mike, John". La méthode prototype étant utilisée, l'opérateur instanceof peut toujours être utilisé pour déterminer le type de l'objet

.

Cette méthode est la principale méthode utilisée par ECMAScript, et elle a d'autres méthodes. Cependant, certains développeurs estiment toujours que cette méthode n'est pas parfaite

Pour les développeurs habitués à d'autres langages, utilisant un hybride. L'approche constructeur/prototype peut sembler moins harmonieuse. Après tout, la plupart des langages orientés objet ont une représentation visuelle des propriétés et des méthodes lors de la définition des classes. Considérez la classe Java suivante :

Java很好地打包了Car类的所有属性和方法,因此看见这段代码就知道它要实现什么功能,它定义了一个对象的信息。批评混合的构造函数/原型方式的人认为,在构造函数内部找属性,在其外部找方法的做法不合逻辑。因此,他们设计了动态原型方法,以提供更友好的编码风格。

动态原型方法的基本想法与混合的构造函数/原型方式相同,即在构造函数内定义非函数属性,而函数属性则利用原型属性定义。唯一的区别是赋予对象方法的位置。下面是用动态原型方法重写的Car:

function Car(Color,Doors,Mpg) { 
 this.color = Color; 
 this.doors = Doors; 
 this.mpg = Mpg; 
 this.drivers = new Array("Mike","John"); 
 //如果Car对象中的_initialized为undefined,表明还没有为Car的原型添加方法 
 if (typeof Car._initialized == "undefined") { 
   Car.prototype.showColor = function() { 
    return this.color; 
   }; 
   Car._initialized = true; //设置为true,不必再为prototype添加方法 
 } 
} 
var Car1 = new Car("red",4,23);//生成一个Car对象 
var Car2 = new Car("blue",3,25); 
Car1.drivers.push("Bill");//向Car1对象实例的drivers属性添加一个元素 
document.write(Car1.drivers+"
");//输出:Mike,John,Bill 
document.write(Car2.drivers);//输出:Mike,John

 直到检查typeof Car._initialize是否等于"undefined"之前,这个构造函数都未发生变化。这行代码是动态原型方法中最重要的部分。如果这个值未定义,构造函数将用原型方式继续定义对象的方法,然后把 Car._initialized设置为true。如果这个值定义了(它的值为 true时,typeof 的值为Boolean),那么就不再创建该方法。简而言之,该方法使用标志(_initialized)来判断是否已给原型赋予了任何方法。该方法只创建并赋值一次,传统的 OOP开发者会高兴地发现,这段代码看起来更像其他语言中的类定义了。 

我们应该采用哪种方式呢?      

如前所述,目前使用最广泛的是混合的构造函数/原型方式。此外,动态原型方式也很流行,在功能上与构造函数/原型方式等价。可以采用这两种方式中的任何一种。不过不要单独使用经典的构造函数或原型方式,因为这样会给代码引入问题。总之JS是基于面向对象的一门客户端脚本语言,我们在学习它的面向对象技术的时候要的留意JS与其他严谨性高的程序语言的不同。也要正确使用JS创建对象的合理的方式,推荐使用构造函数与原型方式的混合方式创建对象实例。这样可以避免许多不必要的麻烦。

以上就是JavaScript基于面向对象之创建对象的全部内容,希望对大家的学习有所帮助。

【相关教程推荐】

1. JavaScript视频教程
2. JavaScript在线手册
3. bootstrap教程

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