webentwicklung-frage-antwort-db.com.de

Die Eigenschaft 'name' des Objekts '[object Object]' kann nicht schreibgeschützt werden

Der folgende Code gibt nur für die name-Eigenschaft einen Fehler aus . Er könnte behoben werden, indem die name-Eigenschaft in Object.create-Argumenten als schreibbar angegeben wird, aber ich versuche zu verstehen, warum dies geschieht (und möglicherweise gibt es eine eleganter Weg, um es zu beheben).

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

Sie können die name-Eigenschaft einer Funktion nicht ändern. Der Deskriptor sagt, dass es nicht writable... ist.

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

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

Da es sich um configurable handelt, können Sie Object.defineProperty() verwenden.

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

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

console.log(BaseClass.name);


EDIT

Ich bin wieder da! Also ... Wie ich bereits in Kommentaren gesagt habe, glaube ich, ich habe dein Problem erkannt. Ich habe etwas zu schnell geantwortet und nicht gesehen, dass Ihre ES5-Vererbung falsch ist.

ExtendedClass.prototype = Object.create(BaseClass); ist nicht das, was Sie tun möchten. Dies bedeutet, dass der Prototyp von ExtendedClass eine Konstruktorfunktion wird. Dies erzeugt offensichtlich ein unerwartetes Verhalten.

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' });

In Ihrem Code ist this eine Funktion und verweist auf BaseClass. Deshalb dürfen Sie den Namen nicht ändern ...

Wenn Sie in JavaScript mit Vererbung arbeiten, benötigen Sie im Allgemeinen diese beiden Zeilen:

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

Hier ist eine gültige Implementierung:

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

Die Variable name ist eine reservierte Eigenschaft des Objekts Function, in das Sie es einzufügen versuchen. Sie können es nicht festlegen.

die Dokumentation für die Name-Eigenschaft befindet sich unter MDN .

3
Misaz

Wenn Sie diesen Fehler in Angular + TypeScript + NgRX erhalten:

Sie können den Spread-Operator verwenden, um eine flache Kopie eines schreibgeschützten Objekts zu erstellen, damit es lesbar ist. Abhängig von Ihrer Situation möchten Sie dies jedoch möglicherweise nicht.

let x = [...y];

Wenn Sie Redux/NgRX verwenden, kann es sein, dass Ihr Selektor ein schreibgeschütztes Objekt mit einem Verweis auf den Speicher zurückgibt, das beim Versuch, diese Objekteigenschaft über die Vorlagenbindung zu ändern, Ausnahmen auslösen kann. Abhängig von Ihrer Situation können Sie eine tiefe Kopie erstellen, um den Geschäftsverweis zu entfernen.

let x = JSON.parse(JSON.stringify(y));
1
user12180028

Wenn Sie diesen Fehler in Angular + TypeScript erhalten:

FALSCH/UNGÜLTIG:

@Output whatever_var = new EventEmitter ();

GUT/KORREKT:

@Output () whatever_var = new EventEmitter ();

1
J.M.I. MADISON