web-dev-qa-db-fra.com

Impossible d'affecter en lecture seule la propriété 'nom' de l'objet '[objet Objet]'

Le code suivant renvoie une erreur uniquement pour la propriété name . Il pourrait être corrigé en spécifiant la propriété name comme accessible en écriture dans les arguments Object.create mais j'essaie de comprendre pourquoi cela se produit} (et peut-être est un moyen plus élégant de le réparer).

var BaseClass = function (data) {
  Object.assign(this, data);
}

var ExtendedClass = function () {
  BaseClass.apply(this, arguments);
}

ExtendedClass.prototype = Object.create(BaseClass);

console.log(new ExtendedClass({ type: 'foo' }));
new ExtendedClass({ name: 'foo' });

6

Vous ne pouvez pas modifier la propriété name d'une fonction. Le descripteur dit que ce n'est pas writable...

var BaseClass = function (data) {
  Object.assign(this, data);
};

console.log(Object.getOwnPropertyDescriptor(BaseClass, 'name'));

Mais puisqu'il s'agit de configurable, vous pouvez utiliser Object.defineProperty().

var BaseClass = function (data) {
  Object.assign(this, data);
};

Object.defineProperty(BaseClass, 'name', {
  writable: true,
  value: 'Foo'
});

console.log(BaseClass.name);


MODIFIER

Je suis revenu! Alors ... Comme je l'ai dit précédemment dans les commentaires, je pense avoir identifié votre problème. J'ai répondu un peu trop vite et je n'ai pas vu que votre héritage ES5 était faux.

ExtendedClass.prototype = Object.create(BaseClass); n'est pas ce que vous voulez faire. Cela signifie que le prototype de ExtendedClass devient une fonction constructeur. Cela génère évidemment un comportement inattendu.

function BaseClass(data) {
  console.log(this instanceof BaseClass); // "this" is not an instance of "BaseClass"
  console.log(this instanceof Function); // "this" is a function
  console.log(this.name); // "this" is "BaseClass"
  
  Object.assign(this, data);
}

function ExtendedClass() {
  BaseClass.apply(this, arguments);
}
ExtendedClass.prototype = Object.create(BaseClass);

new ExtendedClass({ type: 'foo' });

this est dans votre code une fonction et fait référence à BaseClass. C'est pourquoi vous n'êtes pas autorisé à modifier son nom ...

En fait, lorsque vous travaillez avec l'héritage en JavaScript, vous avez généralement besoin de ces deux lignes:

ExtendedClass.prototype = Object.create(BaseClass.prototype);
ExtendedClass.prototype.constructor = ExtendedClass;

Voici une implémentation valide:

function BaseClass(data) {
  console.log(this instanceof BaseClass); // "this" is an instance of "BaseClass"
  console.log(this instanceof Function); // "this" is not a function
  console.log(this.name); // "this" has no name yet
  
  Object.assign(this, data);
}

function ExtendedClass() {
  BaseClass.apply(this, arguments);
}
ExtendedClass.prototype = Object.create(BaseClass.prototype);
ExtendedClass.prototype.constructor = ExtendedClass;

var instance = new ExtendedClass({ name: 'foo' });

console.log(instance.name); // foo
console.log(BaseClass.name); // BaseClass
console.log(ExtendedClass.name); // ExtendedClass

5
Badacadabra

La propriété name est réservée de l'objet Function sur lequel vous essayez de la définir. Vous ne pouvez pas la définir.

la documentation de la propriété name est à MDN .

3
Misaz

Si vous obtenez cette erreur dans Angular + TypeScript :

FAUX/INVALIDE:

@Output Whatever_var = new EventEmitter ();

BON/CORRECT:

@Output () Whatever_var = new EventEmitter ();

1
J.M.I. MADISON