Avant d'apprendre la programmation orientée objet (orientée objet,oo), vous devez d'abord savoir ce qu'est un objet, ECMA -262, définit un objet comme une collection de "attributs non ordonnés, dont les attributs peuvent inclure des valeurs de base, des objets ou des fonctions ". Il existe de nombreuses façons de créer des objets en JavaScript, telles que : le modèle d'usine, le modèle de constructeur, le modèle de prototype, le modèle de constructeur combiné et le modèle de prototype, le modèle de constructeur parasite, etc.
Le modèle d'usine est un modèle de conception bien connu dans le domaine du génie logiciel. Ce modèle résume le processus de création d'objets spécifiques. Considérant que les classes ne peuvent pas être créées dans ECMAScript , les développeurs ont inventé une fonction qui encapsule les détails de la création d'objets avec une interface spécifique.
function createStudent(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 student1= createStudent("xiaoming", 9, "student"); var student2 = createStudent("xiaowagn", 15, "student");
La fonction createStudent() peut construire un objet Student contenant toutes les informations nécessaires en fonction des paramètres acceptés. Cette fonction peut être appelée un nombre illimité de fois, et à chaque fois elle renvoie 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). Avec le développement de JavaScript, un autre nouveau modèle est apparu.
Nous modifions d'abord le code précédent comme suit :
function Student(name,age){ this.name=name; this.age=age; this.showname=function(){ alert(this.name); } } var xiaoming =new Student("xiaoming",6); var xiaogang =new Student("xiaogang",7);
Différence par rapport au modèle d'usine :
1. L'objet créé n'est pas affiché
2. attribue directement les propriétés à cet objet
3. Il n'y a pas de déclaration Retour.
Pour créer une instance, utilisez l'opérateur new.
Étapes pour créer un objet :
1.Créer un nouvel objet
2.Attribuer la portée du constructeur Donner un nouvel objet (ce pointe vers ce nouvel objet)
3.Exécuter le code du constructeur et ajouter des attributs à cet objet
4.Renvoyer cet objet
alert(xiaoming.constructor==Student) //true;
L'attribut constructeur de l'objet était à l'origine utilisé pour identifier un type d'objet. Vérifier un type d'objet ou utiliser des instances sont identifiées comme étant d'un type spécifique et c'est là que le modèle de constructeur surpasse le modèle d'usine ; L'utilisation de constructeurs présente également des inconvénients. C'est-à-dire que chaque méthode doit être recréée sur chaque instance. Par exemple, , xiaoming
alert(xiaoming instanceof Student) //true alert(xiaoming instanceof Object) //true是因为所有对象均继承自Object
xiaogang
ont tous une méthodeshowname() . Mais ces deux méthodes ne sont pas des instances de la même Fonction. Les fonctions dans ECMAScript sont des objets. Par conséquent, chaque fois qu'une fonction est définie, un objet est instancié. D'un point de vue logique, le constructeur peut également être défini ainsi à ce moment-là. Comme vous pouvez le voir, chaque instance Student contient une instance Function différente. Les fonctions portant le même nom sur différentes instances ne sont pas égales. Le code suivant le démontre. 2. Modèle de constructeur
function student(name,age){ this.name=name; this.showName=new Function(“alert(this.name)”); }
function Student(){ } Student.property.name=”default name”; Student.property.age=0; Student.property.showName=funciton(){ alert(this.name); } Var xiaoming=new Student(); Var xiaogang=new Student();
与构造函数模式的不同时,新对象的这些属性和方法是由所有的实例共享的。换句话说xiaoming和xiaogang访问的都是同一组属性和同一个showName()函数。要理解原型模式的工作原理,必须先理解ECMAScript 中原型对象的性质。
1. 理解原型对象
无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype
属性,这个属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个constructor
(构造函数)属性,这个属性包含一个指向prototype 属性所在函数的指针。就拿前面的例子来说,
Student.prototype. constructor 指向Student。而通过这个构造函数,我们还可继续为原型对象添加其他属性和方法.
在JS中我们通过isPropertyOf()来判断,某个实例是否指向某个函数的的原型。
Eg:
Student.property.isPropertyOf(xiaoming);//true。
在ECMAScript5中含增加了Object.getPropertyOf()方法来获取一个实例的原型
Eg:
alert(Object.getPropertyOf(xiaoming)==Student.property);//true alert(Object.getPropertyOf(xiaoming).name);//default name
此外,我们还可以通过hasOwnProperty()方法来检测一个属性是存在实例中还是存在原型中。alert(xiaoming.hasOwnProperty(“name”));//false
alert(xiaoming.property.hasOwnProperty(“name”));//true
原型模式也不是没有缺点。首先,它省略了为构造函数传递初始化参数这一环节,结果所有实例在默认情况下都将取得相同的属性值。虽然这会在某种程度上带来一些不方便,但还不是原型的最大问题。原型模式的最大问题是由其共享的本性所导致的。原型中所有属性是被很多实例共享的,这种共享对于函数非常合适。对于那些包含基本值的属性倒
也说得过去,毕竟(如前面的例子所示),通过在实例上添加一个同名属性,可以隐藏原型中的对应属性。然而,对于包含引用类型值的属性来说,问题就比较突出.
创建自定义类型的最常见方式,就是组合使用构造函数模式与原型模式。构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。结果,每个实例都会有自己的一份实例属性的副本,但同时又共享着对方法的引用,最大限度地节省了内存。另外,这种混成模式还支持向构造函数传递参数;可谓是集两种模式之长。
function Student(name,age){ this.name=name; this.age=age; } Student.property.showName=funciton(){alert(this.name);}
这种构造函数与原型混成的模式,是目前在ECMAScript 中使用最广泛、认同度最高的一种创建自定义类型的方法。可以说,这是用来定义引用类型的一种默认模式。
通常,在前述的几种模式都不适用的情况下,可以使用寄生(parasitic)构造函数模式。这种模式的基本思想是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新创建的对象;但从表面上看,这个函数又很像是典型的构造函数。
funciton Student(name,age){ Var o=new Object(); o.name=name; o.age=age; o.showName=function(){alert(this.name);} Reurn o; }
关于寄生构造函数模式,有一点需要说明:首先,返回的对象与构造函数或者与构造函数的原型属性之间没有关系;也就是说,构造函数返回的对象与在构造函数外部创建的对象没有什么不同。为此,不能依赖instanceof 操作符来确定对象类型。由于存在上述问题,我们建议在可以使用其他模式的情况下,不要使用这种模式。个人感觉这模式还是有点模仿工厂模式。
以上就是JavaScript面向对象编程(对象创建)的内容,更多相关内容请关注PHP中文网(www.php.cn)!