web-dev-qa-db-fra.com

Quel est le meilleur moyen de créer un objet en JavaScript? Est-ce que `var` est nécessaire avant une propriété d'objet?

Jusqu'ici, j'ai vu trois façons de créer un objet en JavaScript. Quel est le meilleur moyen de créer un objet et pourquoi?

J'ai également constaté que dans tous ces exemples, le mot clé var n'est pas utilisé avant une propriété - pourquoi? N’est-il pas nécessaire de déclarer var devant le nom d’une propriété, car il est mentionné que les propriétés sont des variables?

Dans la deuxième et troisième manière, le nom de l'objet est en majuscule alors que dans le premier, le nom de l'objet est en minuscule Quel cas devrions-nous utiliser pour un nom d'objet?

Première manière:

function person(fname, lname, age, eyecolor){
  this.firstname = fname;
  this.lastname = lname;
  this.age = age;
  this.eyecolor = eyecolor;
}

myFather = new person("John", "Doe", 50, "blue");
document.write(myFather.firstname + " is " + myFather.age + " years old.");

Deuxième manière:

var Robot = {
  metal: "Titanium",
  killAllHumans: function(){
    alert("Exterminate!");
  }
};

Robot.killAllHumans();

Troisième voie - Objets JavaScript utilisant la syntaxe de tableau:

var NewObject = {};

NewObject['property1'] = value;
NewObject['property2'] = value;
NewObject['method'] = function(){ /* function code here */ }
160
Jamna

Il n'y a pas de solution best, cela dépend de votre cas d'utilisation.

  • Utilisez way 1 si vous voulez créer plusieurs objets similaires. Dans votre exemple, Person (vous devez commencer le nom par une majuscule) est appelé fonction constructeur. Ceci est similaire à classes dans d'autres OO langues.
  • Utilisez way 2 si vous n'avez besoin que de un objet de la sorte (comme un singleton). Si vous voulez que cet objet hérite d'un autre, vous devez utiliser une fonction constructeur.
  • Utilisez way 3 si vous souhaitez initialiser les propriétés de l'objet en fonction d'autres propriétés de celui-ci ou si vous avez des noms de propriété dynamiques.

Mise à jour: Comme exemples demandés pour la troisième voie.

Propriétés dépendantes:

Ce qui suit ne fonctionne pas comme this ne pas fait référence à book. Il n'y a aucun moyen d'initialiser une propriété avec les valeurs d'autres propriétés dans un littéral d'objet:

var book = {
    price: somePrice * discount,
    pages: 500,
    pricePerPage: this.price / this.pages
};

à la place, vous pourriez faire:

var book = {
    price: somePrice * discount,
    pages: 500
};
book.pricePerPage = book.price / book.pages;
// or book['pricePerPage'] = book.price / book.pages;

Noms de propriétés dynamiques:

Si le nom de la propriété est stocké dans une variable ou créé à l'aide d'une expression, vous devez utiliser la notation entre crochets:

var name = 'propertyName';

// the property will be `name`, not `propertyName`
var obj = {
    name: 42
}; 

// same here
obj.name = 42;

// this works, it will set `propertyName`
obj[name] = 42;
169
Felix Kling

Il y a différentes façons de définir une fonction. Il est totalement basé sur vos besoins. Voici les quelques styles: -

  1. Constructeur d'objet 
  2. Constructeur littéral
  3. Basé sur la fonction
  4. À base de prototypes
  5. Basé sur la fonction et le prototype
  6. Basé sur Singleton

Exemples:

  1. Constructeur d'objet
var person = new Object();

person.name = "Anand",
person.getName = function(){
  return this.name ; 
};
  1. Constructeur littéral
var person = { 
  name : "Anand",
  getName : function (){
   return this.name
  } 
} 
  1. fonction constructeur
function Person(name){
  this.name = name
  this.getName = function(){
    return this.name
  } 
} 
  1. Prototype
function Person(){};

Person.prototype.name = "Anand";
  1. Combinaison fonction/prototype
function Person(name){
  this.name = name;
} 
Person.prototype.getName = function(){
  return this.name
} 
  1. Singleton
var person = new function(){
  this.name = "Anand"
} 

Vous pouvez l'essayer sur console si vous avez une confusion quelconque.

107

Il n'y a pas de "meilleure façon" de créer un objet. Chaque voie a des avantages en fonction de votre cas d'utilisation.

Le modèle de constructeur (une fonction associée à l'opérateur new pour l'invoquer) offre la possibilité d'utiliser l'héritage prototypique, contrairement aux autres méthodes. Donc, si vous voulez un héritage prototype, alors une fonction constructeur est un bon moyen d’aller.

Cependant, si vous voulez un héritage prototype, vous pouvez également utiliser Object.create , ce qui rend l'héritage plus évident.

La création d'un littéral d'objet (ex: var obj = {foo: "bar"};) fonctionne parfaitement si vous disposez de toutes les propriétés que vous souhaitez définir lors de la création.

Pour définir les propriétés ultérieurement, la syntaxe NewObject.property1 est généralement préférable à NewObject['property1'] si vous connaissez le nom de la propriété. Mais ce dernier est utile lorsque vous n'avez pas encore le nom de la propriété à l'avance (ex: NewObject[someStringVar]).

J'espère que cela t'aides!

9
jimbojw

Je suppose que cela dépend de ce que vous voulez. Pour les objets simples, je suppose que vous pourriez utiliser les deuxièmes méthodes. Lorsque vos objets grossissent et que vous envisagez d'utiliser des objets similaires, je suppose que la première méthode serait meilleure. De cette façon, vous pouvez également l'étendre à l'aide de prototypes.

Exemple:

function Circle(radius) {
    this.radius = radius;
}
Circle.prototype.getCircumference = function() {
    return Math.PI * 2 * this.radius;
};
Circle.prototype.getArea = function() {
    return Math.PI * this.radius * this.radius;
}

Je ne suis pas un grand fan de la troisième méthode, mais c'est vraiment utile pour éditer dynamiquement des propriétés, par exemple var foo='bar'; var bar = someObject[foo];.

6
Daan Wilmer

Il existe plusieurs façons de créer vos objets en JavaScript . L’utilisation d’une fonction constructeur pour créer un objet ou une notation littérale d’objet utilise beaucoup de JavaScript. Également en créant une instance de Object, puis en y ajoutant des propriétés et des méthodes, il existe trois façons courantes de créer des objets en JavaScript.

Fonctions constructeur

Il existe des fonctions de constructeur intégrées que nous pouvons tous utiliser de temps à autre, telles que Date (), Number (), Boolean (), etc. Toutes les fonctions de constructeur commencent par une majuscule. Nous pouvons cependant créer une fonction de constructeur personnalisée en JavaScript. comme ça:

function Box (Width, Height, fill) {  
  this.width = Width;  // The width of the box 
  this.height = Height;  // The height of the box 
  this.fill = true;  // Is it filled or not?
}  

et vous pouvez l'invoquer, en utilisant simplement new (), pour créer une nouvelle instance du constructeur, créer quelque chose comme ci-dessous et appeler la fonction constructeur avec des paramètres renseignés:

var newBox = new Box(8, 12, true);  

Littéraux d'objet

L'utilisation de littéraux d'objet est un cas très utilisé de création d'objet en JavaScript, il s'agit d'un exemple de création d'objet simple. Vous pouvez affecter n'importe quoi aux propriétés de l'objet tant qu'elles sont définies:

var person = { 
    name: "Alireza",
    surname: "Dezfoolian"
    nose: 1,  
    feet: 2,  
    hands: 2,
    cash: null
};  

Prototypage

Après avoir créé un objet, vous pouvez créer un prototype pour plus de membres, par exemple en ajoutant de la couleur à notre boîte, nous pouvons le faire:

Box.prototype.colour = 'red';
3
Alireza

Bien sûr, il existe un meilleur moyen. Les objets en javascript ont des propriétés énumérables et non énumérables.

var empty = {};
console.log(empty.toString);
// . function toString(){...}
console.log(empty.toString());
// . [object Object]

Dans l'exemple ci-dessus, vous pouvez voir qu'un objet vide a réellement des propriétés.

Ok voyons d'abord quel est le meilleur moyen:

var new_object = Object.create(null)

new_object.name = 'Roland'
new_object.last_name = 'Doda'
//etc

console.log("toString" in new_object) //=> false

Dans l'exemple ci-dessus, le journal générera une valeur false.

Voyons maintenant pourquoi les autres méthodes de création d'objet sont incorrectes.

//Object constructor
var object = new Object();

console.log("toString" in object); //=> true

//Literal constructor
var person = { 
  name : "Anand",
  getName : function (){
   return this.name
  } 
} 

console.log("toString" in person); //=> true

//function Constructor
function Person(name){
  this.name = name
  this.getName = function(){
    return this.name
  } 
}

var person = new Person ('landi')

console.log("toString" in person); //=> true

//Prototype
function Person(){};

Person.prototype.name = "Anand";

console.log("toString" in person); //=> true

//Function/Prototype combination
function Person2(name){
  this.name = name;
} 

Person2.prototype.getName = function(){
  return this.name
}

var person2 = new Person2('Roland')

console.log("toString" in person2) //=> true

Comme vous pouvez le voir ci-dessus, tous les exemples sont consignés dans true. Cela signifie que si vous avez une boucle for in pour voir si l'objet a une propriété, vous obtiendrez probablement des résultats erronés.

Notez que la meilleure façon, ce n'est pas facile.Vous devez définir toutes les propriétés de l'objet ligne par ligne.Les autres façons sont plus faciles et auront moins de code pour créer un objet, mais vous devez être conscient dans certains cas . J'utilise toujours les "autres moyens" en passant et une solution à l'avertissement ci-dessus si vous n'utilisez pas le meilleur moyen est:  

 for (var property in new_object) {
  if (new_object.hasOwnProperty(property)) {
    // ... this is an own property
  }
 }
0
roli roli

Tandis que beaucoup de gens ici disent qu'il n'y a pas de meilleur moyen de créer des objets, il existe une raison qui explique pourquoi il y a tant de façons de créer des objets en JavaScript, à partir de 2019, et cela est lié au progrès de JavaScript au fil des différentes itérations. des versions EcmaScript remontant à 1997.

Avant ECMAScript 5, il n'y avait que deux façons de créer des objets: la fonction constructeur ou la notation littérale (une meilleure alternative au nouvel objet ()). Avec la notation de fonction constructeur, vous créez un objet qui peut être instancié en plusieurs instances (avec le nouveau mot-clé), tandis que la notation littérale délivre un seul objet, tel qu'un singleton.

// constructor function
function Person() {};

// literal notation
var Person = {};

Quelle que soit la méthode utilisée, les objets JavaScript sont simplement des propriétés de paires clé-valeur:

// Method 1: dot notation
obj.firstName = 'Bob';

// Method 2: bracket notation. With bracket notation, you can use invalid characters for a javascript identifier.
obj['lastName'] = 'Smith';

// Method 3: Object.defineProperty
Object.defineProperty(obj, 'firstName', {
    value: 'Bob',
    writable: true,
    configurable: true,
    enumerable: false
})

// Method 4: Object.defineProperties
Object.defineProperties(obj, {
  firstName: {
    value: 'Bob',
    writable: true
  },
  lastName: {
    value: 'Smith',
    writable: false
  }
});

Dans les premières versions de JavaScript, le seul véritable moyen d'imiter l'héritage basé sur les classes consistait à utiliser des fonctions de constructeur. la fonction constructeur est une fonction spéciale appelée avec le mot clé 'new'. Par convention, l'identifiant de la fonction est en majuscule, albiet n'est pas obligatoire. A l'intérieur du constructeur, nous nous référons au mot clé 'this' pour ajouter des propriétés à l'objet que la fonction constructeur crée implicitement. La fonction constructeur renvoie implicitement le nouvel objet avec les propriétés renseignées à la fonction appelante implicitement, à moins que vous utilisiez explicitement le mot clé return et que vous renvoyiez autre chose.

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;

    this.sayName = function(){
        return "My name is " + this.firstName + " " + this.lastName;
    }
} 

var bob = new Person("Bob", "Smith");
bob instanceOf Person // true

Il y a un problème avec la méthode sayName. En règle générale, dans les langages de programmation basés sur des classes orientées objet, vous utilisez des classes comme fabriques pour créer des objets. Chaque objet aura ses propres variables d'instance, mais un pointeur sur les méthodes définies dans le plan de classe. Malheureusement, lors de l'utilisation de la fonction constructeur de JavaScript, chaque fois qu'elle est appelée, une nouvelle propriété sayName est définie sur l'objet nouvellement créé. Ainsi, chaque objet aura sa propre propriété sayName. Cela consommera plus de ressources mémoire.

Outre l’augmentation des ressources de mémoire, la définition de méthodes à l’intérieur de la fonction constructeur élimine la possibilité d’un héritage. Encore une fois, la méthode sera définie comme une propriété sur le nouvel objet créé et aucun autre objet. Par conséquent, l'héritage ne peut pas fonctionner de la même manière. Par conséquent, JavaScript fournit la chaîne de prototypes sous forme d'héritage, faisant de JavaScript un langage prototype.

Si vous avez un parent et qu'un parent partage de nombreuses propriétés d'un enfant, celui-ci doit hériter de ces propriétés. Avant ES5, cela était accompli comme suit:

function Parent(eyeColor, hairColor) {
    this.eyeColor = eyeColor;
    this.hairColor = hairColor;
}

Parent.prototype.getEyeColor = function() {
  console.log('has ' + this.eyeColor);
}

Parent.prototype.getHairColor = function() {
  console.log('has ' + this.hairColor);
}

function Child(firstName, lastName) {
  Parent.call(this, arguments[2], arguments[3]);
  this.firstName = firstName;
  this.lastName = lastName;
}

Child.prototype = Parent.prototype;

var child = new Child('Bob', 'Smith', 'blue', 'blonde');
child.getEyeColor(); // has blue eyes
child.getHairColor(); // has blonde hair

La façon dont nous avons utilisé la chaîne de prototypes ci-dessus présente une bizarrerie. Étant donné que le prototype est un lien actif, en modifiant la propriété d'un objet de la chaîne de prototypes, vous modifieriez également la propriété d'un autre objet. Évidemment, changer la méthode héritée d'un enfant ne devrait pas changer la méthode du parent. Object.create a résolu ce problème en utilisant un polyfill. Ainsi, avec Object.create, vous pouvez modifier en toute sécurité la propriété d'un enfant dans la chaîne de prototypes sans affecter la même propriété du parent dans la chaîne de prototypes.

ECMAScript 5 a introduit Object.create pour résoudre le bogue susmentionné dans la fonction constructeur pour la création d’objet. La méthode Object.create () CREATE un nouvel objet en utilisant un objet existant comme prototype du nouvel objet créé. Dans la mesure où un nouvel objet est créé, vous ne rencontrez plus le problème suivant: la modification de la propriété enfant dans la chaîne de prototypes modifiera la référence du parent à cette propriété dans la chaîne.

var bobSmith = {
    firstName: "Bob",
    lastName: "Smith",
    sayName: function(){
      return "My name is " + this.firstName + " " + this.lastName;
    }
}

var janeSmith = Object.create(bobSmith, {
    firstName : {  value: "Jane" }
})

console.log(bobSmith.sayName()); // My name is Bob Smith
console.log(janeSmith.sayName()); // My name is Jane Smith
janeSmith.__proto__ == bobSmith; // true
janeSmith instanceof bobSmith; // Uncaught TypeError: Right-hand side of 'instanceof' is not callable. Error occurs because bobSmith is not a constructor function.

Avant ES6, il existait un modèle de création commun qui utilisait les constructeurs de fonctions et Object.create:

const View = function(element){
  this.element = element;
}

View.prototype = {
  getElement: function(){
    this.element
  }
}

const SubView = function(element){
  View.call(this, element);
}

SubView.prototype = Object.create(View.prototype);

Maintenant, Object.create, associé à des fonctions de constructeur, a été largement utilisé pour la création d’objets et l’héritage en JavaScript. Cependant, ES6 a introduit le concept de classes, qui sont principalement du sucre syntaxique par rapport à l'héritage existant basé sur un prototype de JavaScript. La syntaxe de la classe n'introduit pas un nouveau modèle d'héritage orienté objet dans JavaScript. Ainsi, JavaScript reste un langage prototype.

Les classes ES6 facilitent beaucoup l'héritage. Nous n'avons plus besoin de copier manuellement les fonctions prototypes de la classe parent et de réinitialiser le constructeur de la classe enfant.

// create parent class
class Person {
  constructor (name) {
    this.name = name;
  }
}

// create child class and extend our parent class
class Boy extends Person {
  constructor (name, color) {
    // invoke our parent constructor function passing in any required parameters
    super(name);

    this.favoriteColor = color;
  }
}

const boy = new Boy('bob', 'blue')
boy.favoriteColor; // blue

Au total, ces 5 stratégies différentes de création d’objets en JavaScript ont coïncidé avec l’évolution du standard EcmaScript.

0
Donato

Il existe principalement trois façons de créer des objets:

Le plus simple utilise littéraux d'objet .

const myObject = {}

Bien que cette méthode soit la plus simple mais présente un inconvénient, c'est-à-dire que si votre objet a un comportement (fonctions), à l'avenir, si vous souhaitez y apporter des modifications, vous devrez le modifier dans tous les objets .

Donc, dans ce cas, il est préférable d’utiliser les fonctions Factory ou Constructor.

Fonctions d'usine sont les fonctions qui renvoient un objet.e.g-

function factoryFunc(exampleValue){
   return{
      exampleProperty: exampleValue 
   }
}

Fonctions du constructeur sont les fonctions qui attribuent des propriétés aux objets en utilisant "this" keyword.e.g-

function constructorFunc(exampleValue){
   this.exampleProperty= exampleValue;
}
const myObj= new constructorFunc(1);
0
shivam bansal