web-dev-qa-db-fra.com

Renvoie une valeur autre que la classe dans ES6

Récemment, j'ai testé des classes avec ES6. J'ai remarqué que lors de la création d'une classe, vous ne pouvez pas spécifier la valeur donnée par le constructeur.

Auparavant, dans ES5, c'était possible.

Dans les deux cas, je voudrais instancier la classe avec new MyClass La raison pour laquelle je souhaite procéder est que je peux renvoyer un sous-ensemble de la classe actuelle avec uniquement des fonctions.

ES5 - renvoie My class was init with: Blah

var MyClass = function() {
  this.initVar = 'Blah'

  return 'My Class was init with: ' + this.initVar
}

ES6 - renvoie {}

class Bob {
  constructor() {
   return 'hello' 
  }
}
13
MikaAK

Selon le Class article du site Web du TC39, la syntaxe de la classe ES6 a une fonction constructeur implicite appelée si aucune fonction de ce type n'est fournie dans la définition de la classe. 

Cela peut être annulé en fournissant votre propre constructeur et en renvoyant l'objet de votre choix, par exemple:

class Bob {
  constructor(name) {
    return {hi: name};  // returns an object other than *this*.
  }
}

En action:

var bob = new Bob('bob');
console.log(bob.hi); // 'bob'

Pour prolonger la classe, vous pouvez faire:

class Bill extends Bob {
}

Cependant, extend possède également un constructeur implicite, de sorte qu'il renvoie une nouvelle instance de Bill qui hérite de Bob.prototype . Puisque hi a été défini dans le constructeur et non hérité, vous obtenez:

var bill = new Bill('bill');
console.log(bill.hi);  // undefined

Pour initialiser Bill de la même manière que Bob , fournissez un constructeur qui appelle super . Cet appel remplace également le this objet de Bill par la valeur renvoyée par super , par exemple.

class Bill extends Bob {
  constructor(name) {
    super(name);
  }
}

À présent: 

var bill = new Bill('bill');
console.log(bill.hi); // bill

Il convient également de noter que le corps d'un classDeclaration est toujours code de mode strict .

En tant qu'extrait exécutable:

class Bob {
  constructor(name) {
    return {hi: name};  // returns an object other than *this*.
  }
}

var bob = new Bob('bob');
console.log(bob.hi); // 'bob'

class Bill extends Bob {
  constructor(name) {
    super(name);
  }
}

var bill = new Bill('bill');
console.log(bill.hi); // bill

23
RobG

Comparez ces violons: es5 et es6

Ce que vous dites possible dans es5 est toujours possible dans es6. Si vous utilisez un nouveau mot-clé, un nouvel objet est créé pour cette classe. Si vous n'utilisez pas new, la fonction est exécutée.

  1. Ainsi, lorsque vous dites var x= Bob(); à la fois dans es5 et es6, vous exécutez la fonction constructeur, vous ne créez pas de nouvel objet. Il renvoie donc quelque chose.

  2. Et lorsque vous dites, var x= new Bob();, vous obtenez un nouvel objet, initialisé par la fonction constructeur.

Ceci est applicable à es5 et es6, car les classes es6 ne font rien de nouveau, mais sont introduites juste pour des raisons de syntaxe.

Edit : En cas d'extension de classes: Vous ne pouvez pas simplement étendre une classe dans es6 et vous attendre à ce que le super constructeur soit appelé, vous devez l'appeler explicitement à l'intérieur du constructeur de classe enfant .. voir le code:

class Bob {
  constructor() {
    return {hi: 'bob'}
  }
}

class Bill extends Bob {
  constructor() {
   return super();// here you should retun the called super constructer
  }
}

var x=  Bob();
console.log(Bob);

 x= new Bill();
console.log(x.hi);

C'est pourquoi, ceci ne fonctionne pas, mais ceci fonctionne ..

0
Naeem Shaikh

Le ES6 ne renvoie en réalité pas {} mais la classe (constructeur) object dans ce cas. Le constructeur de classe peut renvoyer des objets, mais pas des valeurs primitives. Ainsi, au lieu de [String] "hello", il retourne [Object] Bob. Toute valeur peut être renvoyée de cette façon:

class Bob {
  constructor() {
   return ()=>'hello';
  }
}
const bob = new Bob()();

La [Fonction] renvoyée, étant un objet, peut être renvoyée et immédiatement déclenchée pour renvoyer une valeur primitive, par exemple. [Chaîne] "hello".

0
Paweł