Maison > Article > interface Web > Résumé de la façon de créer des objets en JavaScript (super classique)
Ce que cet article vous apporte est un résumé de la façon de créer des objets en JavaScript (super classique). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
Il existe de nombreuses façons de créer des objets en JavaScript. Vous pouvez également créer un seul objet via le constructeur Object ou le littéral d'objet. Évidemment, ces deux méthodes généreront beaucoup de code répété et ne conviennent pas à la production de masse. . Nous présenterons ensuite sept manières très classiques de créer des objets. Elles ont chacune leurs propres avantages et inconvénients. (Le contenu provient principalement de "JavaScript Advanced Programming", et fait également référence à des articles écrits par d'autres)
1 Le mode usine
function createPerson(name, job) { var o = new Object() ; o.name = name ; o.job = job ; o.sayName = function() { console.log(this.name) } return o } var person1 = createPerson('Mike', 'student') var person2 = createPerson('X', 'engineer')
peut être qualifié d'innombrables. times Cette fonction d'usine renverra à chaque fois un objet contenant deux 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 l'identification des objets, c'est-à-dire qu'il ne peut pas connaître le type d'un objet.
2. Mode constructeur
function Person(name, job) { this.name = name ; this.job = job ; this.sayName = function() { console.log(this.name) } } var person1 = new Person('Mike', 'student') var person2 = new Person('X', 'engineer')
Aucune création d'objet n'est affichée. Utilisez new pour appeler ce constructeur. Après avoir utilisé new, les opérations suivantes seront automatiquement effectuées. :
① Créer un nouvel objet ;
② Attribuer la portée du constructeur au nouvel objet (pour que cela pointe vers le nouvel objet
③ Exécuter le code dans le constructeur (ajouter des attributs à ce nouvel objet) ; object );
④Renvoyer le nouvel objet.
Inconvénient : Chaque méthode doit être recréée sur chaque instance.
Il n'est vraiment pas nécessaire de créer deux instances de Function qui accomplissent la même tâche. De plus, avec cet objet, il n'est pas nécessaire de lier la fonction à un objet spécifique avant d'exécuter le code. Il peut être défini sous cette forme :
function Person( name, age, job ){ this.name = name; this.age = age; this.job = job; this.sayName = sayName; } function sayName(){ alert( this.name ); }
De cette façon, la fonction sayName() peut. be La définition est déplacée en dehors du constructeur. Dans le constructeur, nous définissons la propriété sayName sur la fonction globale sayName. Dans ce cas, puisque sayName contient un pointeur vers une fonction, les objets person1 et person2 peuvent partager la même fonction sayName() définie dans la portée globale.
Cela résout le problème de deux fonctions faisant la même chose, mais un nouveau problème surgit : une fonction définie dans la portée globale ne peut en fait être appelée que par un certain objet, ce qui rend la portée globale. Le domaine est un un terme un peu abusif. Et plus important encore : si l'objet doit définir de nombreuses méthodes, alors de nombreuses fonctions globales doivent être définies. De cette manière, notre type de référence personnalisé n'a aucune encapsulation.
Ces problèmes peuvent être résolus en utilisant le mode prototype.
3. Mode Prototype
function Person() { } Person.prototype.name = 'Mike' Person.prototype.job = 'student' Person.prototype.sayName = function() { console.log(this.name) } var person1 = new Person()
Ajoutez des informations directement à l'objet prototype. L'avantage d'utiliser un prototype est que tous les objets d'instance peuvent partager les propriétés et les méthodes qu'il contient. Au lieu de définir les informations d'instance d'objet dans le constructeur, ces informations peuvent être ajoutées directement à l'objet prototype.
① Comprendre les prototypes
Chaque fois qu'une nouvelle fonction est créée, un attribut de prototype est créé pour la fonction selon un ensemble de règles spécifiques.
Par défaut, tous les attributs prototype obtiendront automatiquement un attribut constructor (constructeur), qui contient un pointeur vers la fonction où se trouve l'attribut prototype .pointeur.
Chaque fois que le code lit une propriété d'un objet, une recherche est effectuée, ciblant la propriété portant le nom donné. La recherche commence par l'instance d'objet elle-même. Si un attribut portant le nom donné est trouvé dans l'instance, la valeur de l'attribut est renvoyée ; s'il n'est pas trouvé, l'objet prototype pointé par le pointeur est recherché et l'attribut portant le nom donné est trouvé dans l'objet prototype. Si cette propriété est trouvée dans l'objet prototype, la valeur de cette propriété est renvoyée.
Bien que les valeurs stockées dans le prototype soient accessibles via l'instance d'objet, les valeurs du prototype ne peuvent pas être remplacées via l'instance d'objet.
Si nous ajoutons une propriété à l'instance et que la propriété a le même nom qu'une propriété dans l'instance, alors la propriété sera créée dans l'instance et la propriété masquera cette propriété dans le prototype.
Même si l'attribut est défini sur null, la valeur de l'attribut est nulle uniquement dans l'instance.
Cependant, les propriétés de l'instance peuvent être complètement supprimées à l'aide de l'opérateur delete, permettant ainsi d'accéder à nouveau aux propriétés du prototype.
Utilisez la méthode hasOwnProperty() pour détecter si une propriété existe dans l'instance ou dans le prototype. Cette méthode renverra true uniquement si la propriété donnée existe dans l'instance d'objet.
②Prototype et opérateur in
L'opérateur in retournera vrai lorsqu'une propriété donnée est accessible via l'objet, que la propriété existe dans l'instance ou dans le prototype.
③Syntaxe du prototype plus simple
function Person(){ } Person.prototype = { name : "Mike", age : 29, job : "engineer", syaName : function(){ alert( this.name ); } };
//Dans le code ci-dessus, Person.prototype est défini comme égal à un nouvel objet créé sous la forme d'un objet littéral. Le résultat final est le même, à une exception près : la propriété constructeur ne pointe plus vers la personne.
4. Utilisation combinée du modèle constructeur et du modèle prototype
组合使用构造函数模式和原型模式是使用最为广泛、认同度最高的一种创建自定义类型的方法。它可以解决上面那些模式的缺点,使用此模式可以让每个实例都会有自己的一份实例属性副本,但同时又共享着对方法的引用,这样的话,即使实例属性修改引用类型的值,也不会影响其他实例的属性值了。还支持向构造函数传递参数,可谓是集两种模式的优点。
function Person(name) { this.name = name this.friends = ['Jack', 'Merry'] } Person.prototype.sayName = function() { console.log(this.name) } var person1 = new Person() var person2 = new Person() person1.friends.push('Van') console.log(person1.friends) //["Jack", "Merry", "Van"] console.log(person2.friends) // ["Jack", "Merry"] console.log(person1.friends === person2.friends) //false
五、动态原型模式
动态原型模式将所有信息都封装在了构造函数中,初始化的时候。可以通过检测某个应该存在的方法是否有效,来决定是否需要初始化原型。
function Person(name, job) { // 属性 this.name = name this.job = job // 方法 if(typeof this.sayName !== 'function') { Person.prototype.sayName = function() { console.log(this.name) } } } var person1 = new Person('Mike', 'Student') person1.sayName()
只有在sayName方法不存在的时候,才会将它添加到原型中。这段代码只会初次调用构造函数的时候才会执行。此后原型已经完成初始化,不需要在做什么修改了,这里对原型所做的修改,能够立即在所有实例中得到反映。
其次,if语句检查的可以是初始化之后应该存在的任何属性或方法,所以不必用一大堆的if语句检查每一个属性和方法,只要检查一个就行。
六、寄生构造函数模式
这种模式的基本思想就是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新建的对象
function Person(name, job) { var o = new Object() o.name = name o.job = job o.sayName = function() { console.log(this.name) } return o } var person1 = new Person('Mike', 'student') person1.sayName()
这个模式,除了使用new操作符并把使用的包装函数叫做构造函数之外,和工厂模式几乎一样。
构造函数如果不返回对象,默认也会返回一个新的对象,通过在构造函数的末尾添加一个return语句,可以重写调用构造函数时返回的值。
七、稳妥构造函数模式
首先明白稳妥对象指的是没有公共属性,而且其方法也不引用this。稳妥对象最适合在一些安全环境中(这些环境会禁止使用this和new),或防止数据被其他应用程序改动时使用。
稳妥构造函数模式和寄生模式类似,有两点不同:1.是创建对象的实例方法不引用this;2.不使用new操作符调用构造函数
function Person(name, job) { var o = new Object() o.name = name o.job = job o.sayName = function() { console.log(name) } return o } var person1 = Person('Mike', 'student') person1.sayName()
和寄生构造函数模式一样,这样创建出来的对象与构造函数之间没有什么关系,instanceof操作符对他们没有意义
相关推荐:
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!