31 votes

Utiliser `super ()` lors de l'extension de `Object`

Je crée une classe qui étend la classe Object en JavaScript et attendent super() d'initialiser les clés/valeurs lors de la construction d'une nouvelle instance de cette classe.

class ExtObject extends Object {
  constructor(...args) {
    super(...args);
  }
}

const obj = new Object({foo:'bar'});
console.log(obj); // { foo: 'bar' }

const ext = new ExtObject({foo:'bar'});
console.log(ext); // ExtObject {}

console.log(ext.foo); // undefined

Pourquoi n'est-ce pas foo défini comme 'bar' sur ext dans cet exemple?

MODIFIER

Explication: à l'Aide de "super()` lors de l'extension de l ` "Objet"

Solution: à l'Aide de "super()` lors de l'extension de l ` "Objet"

11voto

Felix Kling Points 247451

Personne n'a vraiment expliqué pourquoi il ne fonctionne pas. Si nous regardons au plus tard spec, l' Object fonction est définie comme suit:

19.1.1.1 Object ( [ valeur ] )

Lors de l' Object fonction est appelée avec un argument optionnel value, les mesures suivantes sont prises:

  1. Si NewTarget n'est ni undefined ni la fonction active, alors
    1. De retour ? OrdinaryCreateFromConstructor(NewTarget, "%ObjectPrototype%").
  2. Si value est null, undefined ou n'est pas fourni, le retour ObjectCreate(%ObjectPrototype%).
  3. De retour ! ToObject(value).

La première étape est le plus important ici: NewTarget se réfère à la fonction qu' new a été appelé. Donc, si vous n' new Object, il sera Object. Si vous appelez new ExtObject il ExtObject.

Parce qu' ExtObject n'est Object ("ni la fonction active"), la condition est satisfaite et OrdinaryCreateFromConstructor est évaluée et son résultat retourné. Comme vous pouvez le voir, rien n'est fait avec l' value passés à la fonction.

value n'est utilisé que si ni 1. ni 2. sont remplies. Et si value est un objet, il est tout simplement rendu comme tel, pas de nouvel objet est créé. Donc, new Object(objectValue) est en fait le même que Object(objectValue):

var foo = {bar: 42};
console.log(new Object(foo) === foo);
console.log(Object(foo) === foo);

En d'autres termes: Object ne permet pas de copier les propriétés de l'objet, il retourne simplement l'objet tel qu'il est. Afin d'étendre Object ne serait pas copier les propriétés.

5voto

Tambo Points 4305

Il vous manque le Object.assign

 class ExtObject extends Object {
  constructor(...args) {
    super(...args);
    Object.assign(this, ...args);
  }
}

const obj = new Object({foo:'bar'});
console.log(obj); // { foo: 'bar' }

const ext = new ExtObject({foo:'bar'});
console.log(ext); // { foo: 'bar' }

console.log(ext.foo); // bar 

5voto

barbsan Points 2654

Cette réponse ne fonctionne que lors de l'utilisation de la Babel transpiler.

Parce que constructeur de l'Objet renvoie une valeur. Voir les spec

15.2.2.1 new Object ( [ valeur ] )
Lorsque le constructeur de l'Objet est appelé sans argument, ou avec une valeur de l'argument, les mesures suivantes sont prises:
...
8. Retourne obj.

class ExtObject extends Object {
  constructor(...args) {
    return super(...args);
  }
}

const obj = new Object({foo:'bar'});
console.log(obj); // { foo: 'bar' }

const ext = new ExtObject({foo:'bar'});
console.log(ext); // { foo: 'bar' }

console.log(ext.foo); // bar

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X