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' });
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
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 .
Si vous obtenez cette erreur dans Angular + TypeScript :
FAUX/INVALIDE:
@Output Whatever_var = new EventEmitter ();
BON/CORRECT:
@Output () Whatever_var = new EventEmitter ();