Maison > Article > interface Web > 7 façons classiques de créer des objets en JavaScript (résumé)
Recommandations associées : "Tutoriel vidéo javascript"
Il existe de nombreuses façons de créer des objets en JavaScript, via le constructeur d'objet ou le littéral d'objet. Vous pouvez également créer un seul objet. Évidemment, ces deux méthodes généreront beaucoup de code répété et ne conviennent pas à une 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)
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')
. Cette fonction d'usine peut être appelée un nombre illimité de fois, et à chaque fois elle renvoie 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 la reconnaissance des objets, c'est-à-dire qu'il ne peut pas connaître le type d'un objet.
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')
Il n'y a pas de création d'objet affichée, utilisez new pour appeler ce constructeur, il sera exécuté automatiquement après utilisation. new Fonctionne comme suit :
① Créez un nouvel objet
② Attribuez la portée du constructeur au nouvel objet (pour qu'il pointe vers le nouvel objet
) ; ③ Exécutez le code dans le constructeur (ajoutez des attributs à ce nouvel objet
④ Renvoyez le nouvel objet);
Inconvénients : 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. Elle peut être définie 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 être définie. Sortez 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 : les fonctions définies dans la portée globale ne peuvent en fait être appelées que par un certain objet, ce qui rend la portée globale Le domaine est un peu d'un terme impropre. 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.
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 du prototype obtiendront automatiquement un attribut constructeur, qui contient un pointeur vers la fonction où se trouve l'attribut prototype.
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 recherché dans l'objet prototype. Si la propriété est trouvée dans l'objet prototype, la valeur de la 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 renvoie true lorsqu'une propriété donnée est accessible via l'objet, que la propriété existe dans l'instance ou dans le prototype milieu.
③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éé en tant que littéral d'objet. Le résultat final est le même, à une exception près : la propriété constructeur ne pointe plus vers la personne.
组合使用构造函数模式和原型模式是使用最为广泛、认同度最高的一种创建自定义类型的方法。它可以解决上面那些模式的缺点,使用此模式可以让每个实例都会有自己的一份实例属性副本,但同时又共享着对方法的引用,这样的话,即使实例属性修改引用类型的值,也不会影响其他实例的属性值了。还支持向构造函数传递参数,可谓是集两种模式的优点。
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) //注意这里没有了"this"; } 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!