J'ai vu quelques façons différentes d'instancier des objets en javascript, je voulais connaître les avantages/inconvénients des différentes approches et pourquoi vous utiliseriez l'une sur l'autre.
approche 1
var obj = {
prop: value,
.
.
.
}
La première approche est une approche standard, rien de nouveau :)
approche 2
var obj = new function() {
var prop1 = value1;
var fn1 = function() {
};
.
.
.
this.prop2 = value2;
.
.
.
}();
L'approche fonction, je voulais comparer cette approche avec l'approche 3. L'approche fonction est principalement utilisée pour l'encapsulation (correct?)
approche
var obj = (function() {
var prop1 = value1;
var fn1 = function() {
};
.
.
.
return {
prop2: value2,
.
.
.
}
})();
Avec cette approche, je ne vois pas très bien le raisonnement derrière son utilisation. En quoi diffère-t-il de l'approche 2? Les deux peuvent être utilisés pour encapsuler la logique.
Est-ce pour que nous puissions passer des paramètres, afin de pouvoir faire face à tout conflit potentiel ?? Par exemple, jquery's $
syntaxe - mais vous pouvez aussi le faire avec l'approche 2 ...
Merci.
Modifier:
Je suis conscient que les approches 1 et 3 sont similaires (en ce qu'elles retournent toutes deux des objets), mais l'approche 3 crée également une fermeture. Quelle approche 2 fait également.
C'est la base de ma question vraiment, les deux et trois créent des fermetures, mais quelle est la différence entre eux.
Dans les approches # 2 et # 3, la propriété constructor
des objets résultants sera différente.
En pratique, cela signifie que la deuxième approche vous permet d'instancier plus d'un objet à l'aide de la fonction constructeur anonyme:
x = new function() { alert(1) };
y = new x.constructor; // shows the message too
La meilleure réponse à modèle de module vs instance d'un constructeur anonyme comprend une citation de Douglas Crockford dans laquelle il explique pourquoi il pense que l'approche # 3 est meilleure que # 2.
7 façons de créer des objets en JavaScript:
1. Constructeur d'objet
La façon la plus simple de créer un objet est d'utiliser le constructeur d'objet: voir plainprint?
var person = new Object();
person.name = "Diego";
person.getName = function(){
return this.name;
};
2. Notation littérale
voir plainprint?
var person = {
person.name : "Diego",
person.getName : function(){
return this.name;
}
}
. Fonction d'usine
La fonction Factory permet d'encapsuler et de réutiliser la logique pour créer des objets similaires. Il s'appuie sur l'une des constructions précédentes pour cela. Soit: afficher le plainprint?
var newPerson=function(name){
var result = new Object();
result.name = name;
result.getName = function(){
return this.name;
};
return result;
};
var personOne = newPerson("Diego");
var personTwo = newPerson("Gangelo");
console.log(personOne.getName()); // prints Diego
console.log(personTwo.getName()); // prints Gangelo
Ou:
view plainprint?
var newPerson=function(name){
return {
person.name : name,
person.getName : function(){
return this.name;
};
};
var personOne = newPerson("Diego");
var personTwo = newPerson("Gangelo");
console.log(personOne.getName()); // prints Diego
console.log(personTwo.getName()); // prints Gangelo
4. Constructeur de fonctions
En Javascript, il est possible d'appeler n'importe quelle fonction avec le nouvel opérateur devant lui. Étant donné une fonction F, pour le nouveau F (): un nouvel objet vide X est créé. X est défini comme contexte pour F signifiant tout au long de F cela pointe vers X. X est renvoyé comme résultat de F vue plainprint?
function Person(name){
this.name = name;
this.getName = function(){
return this.name;
};
};
var personOne = new Person("Diego");
console.log(personOne.getName()); // prints Diego
console.log(personOne instanceOf Person); // prints true
console.log(personOne.constructor === Person); // prints true
console.log(personOne instanceOf Object); // prints true
5. Prototype
Les fonctions sont très spéciales en Javascript. Ce sont des objets, ils peuvent créer d'autres objets et ils obtiennent automatiquement un champ appelé prototype. Un prototype est un objet simple avec un seul champ, appelé constructeur, pointant vers la fonction elle-même. Ce qui le rend spécial, c'est que chaque objet créé via une fonction hérite du prototype de la fonction. voir plainprint?
function Person(){};
Person.prototype.name = "Diego";
var personOne = new Person();
var personTwo = new Person();
console.log(personOne.constructor == Person); // prints true
console.log(personOne.name); // prints Diego
console.log(personTwo.constructor == Person); // prints true
console.log(personTwo.name); // prints Diego
6. Combinaison fonction/prototype
La combinaison fonction/prototype, comme vous l'imaginez, tire parti des deux approches :) voir plainprint?
function Person(name){
this.name = name;
};
Person.prototype.getName = function(){
return this.name;
};
var personOne = new Person("Diego");
var personTwo = new Person("Filippo");
console.log(personOne.getName()); // prints Diego
console.log(personTwo.getName()); // prints Filippo
console.log(personOne.getName === personTwo.getName) //prints true
7. Singleton
Parfois, vous pouvez vous assurer qu'il n'existe qu'une seule instance d'une certaine classe. Obtenir un Singleton en Javascript est aussi simple que de définir et d'invoquer le constructeur en même temps: voir plainprint?
var singleton = new function(){
this.name = "ApplicationName";
};
La première et la troisième approche sont presque les mêmes, dans le sens où elles créent toutes deux un objet littéral, qui est un enfant direct de la classe Object
. La différence entre eux est que dans la troisième approche, vous pouvez avoir une sorte d'encapsulation des propriétés:
var obj = (function() {
var prop = {};
return {
prop2: function(){ return prop };
}
})();
En termes de performances, vous pourriez considérer que la troisième approche crée une fermeture, tandis que la première ne le fait pas!
Cependant, dans la deuxième approche, vous créez simplement un nouvel objet à partir d'une classe anonyme qui n'est pas un enfant direct de la classe Object
.
La forme correcte de la deuxième approche est la suivante (du moins c'est la norme ecma):
var obj = new function() {
var prop1 = value1;
this.prop2 = value2;
}();
La différence entre l'approche 2 et 3 n'est que leur chaîne d'héritage: (en supposant que obj2 est de la 2ème approche et obj3 est de la 3ème approche)
obj2.__proto__ == Object.prototype; // false
obj3.__proto__ == Object.prototype; // true
obj2 est créé à partir d'une classe anonyme elle-même:
obj2.__proto__.__proto__ == Object.prototype; // true (there's 2 level of inheritance here)
Il y a aussi:
var obj = Object.create({prop: ...});
Cela fonctionne en définissant un prototype. Il est beaucoup plus efficace d'utiliser un prototype si vous prévoyez d'avoir plusieurs objets partageant des propriétés ou des méthodes.
var proto = {foo: function() {}},
obj1 = Object.create(proto),
obj2 = Object.create(proto),
obj3 = {foo: function() {}},
obj4 = {foo: function() {}};
Dans cet exemple, obj1 et obj2 partagent une fonction "foo", définie dans "proto". Pendant ce temps, obj3 et obj4 ont chacun leur propre "foo". Si vous créez de nombreux objets avec de nombreuses propriétés, cela peut faire une grande différence dans la consommation de mémoire et même les performances.
Cet avantage est partagé par l'utilisation du mot-clé "new" si vous utilisez une fonction nommée et attribuez des propriétés au prototype de la fonction (ex: f.prototype.prop) avant d'utiliser new.
Approche 1
Ceci est un objet unique, pas de classe et vous ne pouvez pas définir plus facile s'il est complexe
var obj = {
prop: value
}
Approche 2
Une fonction non anonyme. Il créera un objet à partir d'une `` classe '', normalement la fonction est enregistrée en tant que nom de classe et peut facilement créer plusieurs objets du même type comme ci-dessous:
var Bycicle= function() {
var prop1 = value1;
this.prop2 = value2;
}
var obj1 = new Bycicle(),
obj2 = new Bycicle();
Approche 3
Fonction anonyme, les variables extérieures à la fonction ne peuvent pas interférer avec les variables internes à la fonction:
var a = 10;
var obj = (function() {
alert(a); // Alerts undefined
var prop1 = value1;
alert(prop1); // alerts the value of value1
return {
prop2: value2;
}
})(); // Within the () you can pass arguments to the anonymous function.
En savoir plus sur les fonctions anonymes: http://helephant.com/2008/08/23/javascript-anonymous-functions/
Autres approches
Il existe également une Object.create()
et une new Object()
pour créer de nouveaux objets, tous deux identiques à l'approche 1.
Conclusion
Au final, l'objet sera toujours le même sauf le 3ème, car il est anonyme.
J'ai un peu travaillé avec JS et j'ai pensé à poster une réponse, j'espère que cela aide aussi quelqu'un d'autre:
1) Objet littéral : Vous avez écrit l'objet littéraire lors de sa création
var person = {
name: ['Bob', 'Smith'],
age: 32,
gender: 'male',
interests: ['music', 'skiing'],
bio: function() {
alert(this.name[0] + ' ' + this.name[1] + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
},
greeting: function() {
alert('Hi! I\'m ' + this.name[0] + '.');
}
};
Utilisation: lorsque vous souhaitez transférer des données vers le serveur
2) Fonction constructeur: Vous utilisez la fonction constructeur lorsque vous souhaitez créer plusieurs objets de même valeur.
function Vehicle(name, maker) {
this.name = name;// Every function while executing has a reference
this.maker = maker;// to its current execution context called as this
}
let car1 = new Vehicle(’Fiesta’, 'Ford’);// New keyword with function turns function call into constructor call
let car2 = new Vehicle(’Santa Fe’, 'Hyundai’);
console.log(car1.name); //Output: Fiesta
console.log(car2.name); //Output: Santa Fe
3) Créer un objet Javascript avec la méthode create
Object.create () permet de créer des objets avec plus d'options d'attribut comme valeur, configurable, énumérable et inscriptible. Crée un nouvel objet étendant l'objet prototype passé en paramètre
let car = Object.create(Object.prototype,{
name:{
value: 'Fiesta',
configurable: true,
writable: true,
enumerable: false
},
maker:{
value: 'Ford',
configurable: true,
writable: true,
enumerable: true
}});
console.log(car.name) //Output: Fiesta
Prototype: chaque objet est construit par une fonction constructeur. La fonction constructeur rend l'objet lié à son propre prototype Le prototype est le lien arbitraire entre le constructeur et l'objet.
4) Créer Javascript à l'aide des classes ES6
class Vehicle {
constructor(name, maker, engine) {
this.name = name;
this.maker = maker;
this.engine = engine;
}
}
let bike1 = new Vehicle('Hayabusa', 'Suzuki', '1340cc');
let bike2 = new Vehicle('Ninja', 'Kawasaki', '998cc');
console.log(bike1.name); //Output: Hayabusa
console.log(bike2.maker); //Output: Kawasaki
5) Utilisation du constructeur d'objet
var d = new Object();
Le meilleur moyen de créer des objets vides.
Remarque: j'ai compilé la plupart des contenus de ce lien https://codeburst.io/various-ways-to-create-javascript-object-9563c6887a47
Afin de comprendre l'approche 2, le lecteur doit connaître certaines choses assez techniques sur le fonctionnement du nouveau mot-clé. Plus précisément, il appellera en fait la fonction anonyme en tant que constructeur, plutôt que d'instancier un nouvel objet fonction et de le vider dans la variable obj.
Pour comprendre l'approche 3, le lecteur a juste besoin de comprendre le modèle IIFE. Ce modèle est devenu très courant dans le code javascript au cours des deux dernières années, et c'est probablement pourquoi cette version est plus couramment utilisée.
Les deux versions sont utilisées pour produire l'encapsulation, et les deux versions nécessitent la connaissance d'une langue complexe pour comprendre. Cependant, la fonctionnalité linguistique requise dans l'approche trois est plus connue que la fonctionnalité linguistique requise pour comprendre l'approche deux. C'est pourquoi l'approche trois est plus couramment utilisée dans la nature.
Il n'y a pas beaucoup de différence entre les approches 2 et 3 pour les objets uniques. (Si vous deviez nommer la fonction utilisée dans l'approche 2, vous auriez défini un constructeur réutilisable.) Mon impression est que l'approche 3 est plus couramment utilisée pour ces situations, mais je ne vois pas beaucoup de différence entre elles.
Il convient de noter que les deux approches 2 et 3 peuvent prendre des arguments:
var approach2Obj = new function(formalArg) {
var privateProp = ...;
this.publicProp = ...;
// more constructor logic
)(actualArg);
var approach3Obj = (function(formalArg) {
var privateProp = ...;
// more creation logic
return {
publicProp : ...;
};
}(actualArg));
P.S. Comme @ Alexey Lebedev le souligne dans sa réponse , une différence entre les deux (peut-être la seule) est que approach2Obj.constructor
et approach3Obj.constructor
sera différent. approach3Obj.constructor
sera identique Object
, tandis que approach2Obj.constructor
sera la fonction anonyme.
Votre question devrait être 2 Approches car Approche est exactement comme Approche 1 seulement la façon de créer qui est par la fonction auto-exécutée.
À propos de la différence lorsque vous créez un objet comme approche 1 vous pouvez y penser comme un objet avec uniquement une fonction statique comme en Java. donc il est toujours vivant et vous n'en faites pas d'instance (similaire à singleton) - donc quand vous faites cet objet:
var obj = {
prop: value,
func: function(){
alert(this.prop);
}
};
Vous pouvez l'appeler immédiatement:
obj.prop = 'something else';
obj.func();
Approche 2 (sans le nouveau comme le commentaire que vous avez) est un objet classique que vous pouvez créer des instances - faire hériter (avec des "trucs" js) et ainsi de suite:
function Person(firstName,lastName){ // or var Person = function(...
this.firstName = firstName;
this.lastName= lastName;
this.getFullName = function(){
return this.firstName + ' ' + this.lastName;
}
}
//use
var person1 = new Person('yair','lapid');
var person2 = new Person('Naftali','Bennet');
you can put it in an array etc...
var arr = [person1,person2, new Person('shelly','yekimovits')];