Warum können wir einige eingebaute Eigenschaften eines globalen Objekts löschen?

12

Ich lese es5 in diesen Tagen und stelle fest, dass das Attribut [[konfigurierbar]] in einigen integrierten Eigenschaften des globalen Objekts auf true festgelegt ist, was bedeutet, dass wir diese Eigenschaften löschen können.

Beispielsweise:

Die Join-Methode des Array.prototype-Objekts verfügt über Attribute

{[[Writable]]:true, [[Enumerable]]: false, [[Configurable]]: true}

So können wir die Join-Methode für Array einfach löschen:

delete Array.prototype.join;
alert([1,2,3].join);

Die Warnung wird undefinedin meinem Chrom 17, Firefox 9, dh 10, sogar ie6 angezeigt;

In Chrome 15 und Safari 5.1.1 ist das Attribut [[konfigurierbar]] auf true festgelegt und das Ergebnis zum Löschen ist ebenfalls true, das Endergebnis ist jedoch weiterhin gültig function(){[native code]}. Scheint, als wäre dies ein Bug und Chrom behebt ihn.

Das habe ich vorher noch nicht bemerkt. Meiner Meinung nach ist das Löschen von integrierten Funktionen im Code des Benutzers gefährlich und führt zu so vielen Fehlern bei der Arbeit mit anderen. Warum trifft ECMAScript diese Entscheidung?

entmischen
quelle
Mehrere Antworten loben die Möglichkeit, die integrierte Funktionalität anzupassen, indem Eigenschaften gelöscht werden. Dieser Ansatz ist jedoch nur erforderlich, da die Funktionalität in globalen Variablen fest verdrahtet ist, anstatt DI zu verwenden. Das Anpassen durch Löschen von Eigenschaften scheint ein Hack um ein grundlegend schlechtes Design zu sein. Wenn Sie beispielsweise den JSON-Parser ändern müssen, können Sie Code schreiben, der einen JSON-Parser als Eingabe verwendet.
Setzen Sie Monica

Antworten:

2

Ich stimme Ihnen eher zu, aber andererseits habe ich gerade eine Situation gefunden, die ich unter delete JSON.stringifybestimmten Umständen aufgrund eines Fehlers in Firefox 3.5 benötigte . Ich war auf jeden Fall froh, dass dort Affen-Patches eingebaut werden konnten.

N3dst4
quelle
Warum überschreibst du es nicht einfach?
Demix
2
Als Nächstes wird JSON2.js geladen, das das Vorhandensein von JSON2 erkennt JSON.stringifyund bei Bedarf injiziert. Entschuldigung, das habe ich in meiner Antwort nicht erklärt.
N3dst4
So können Sie auch den Quellcode json2.js ändern können, lol
entmischen
Es ist eine schlechte Idee, Bibliotheken von Drittanbietern zu ändern, da Sie sie dann nicht aktualisieren können, ohne alle Ihre Änderungen zu kopieren.
N3dst4
1

Konfigurierbar geht es nicht um Löschen.

Es geht um die Möglichkeit , einen schreibgeschützten Wert zu ersetzen.

Es ist ein sehr leistungsfähiges Tool, und nicht konfigurierbare Werte sind frustrierend, wenn Sie sie nicht löschen können.

Ich hatte einige Fälle, in denen ich einen obskuren Fehler beheben oder etwas andere Funktionen (Abfangen, Protokollieren) einschleusen musste. Das zu tun erfordert Ersetzen Sie den Wert.

Beispiel:

Object.defineProperty(Object.prototype, "foo", {
  value: 42,
  configurable: true
});

var o = {};
o.foo = 50; // fails. foo is not writable
delete Object.prototype.foo;
o.foo = 50; // succeeds
/* optionally put Object.prototype.foo back */

Die ganze Idee ist, dass, wenn Sie Eigenschaften löschen können, Sie mehr Metaprogrammiersteuerung haben. Wenn Sie sie nicht löschen könnten, würden Sie sich nur über die Sprache ärgern.

Es gibt keinen guten Grund, Objekte nicht löschbar zu machen, außer Menschen zu ärgern.

Raynos
quelle
1
Das Attribut [[beschreibbar]] steuert die Möglichkeit, den Wert zu ändern. In ES5: [[beschreibbar]] Boolescher Wert Wenn false, schlagen Versuche des ECMAScript-Codes, das Attribut [[Wert]] der Eigenschaft mit [[Put]] zu ändern, fehl . [[Konfigurierbar]] Boolean Wenn false, schlägt der Versuch fehl, die Eigenschaft zu löschen, die Eigenschaft in eine Accessor-Eigenschaft zu ändern oder ihre Attribute (außer [[Wert]]) zu ändern.
24.11.11
@demix Ja, das ist richtig ...
Raynos
0

..delete integrierte Funktionen im Code des Benutzers ist gefährlich

Ganz im Gegenteil. Das Zulassen von Anpassungen ist gut, da Autoren von Websites dadurch mehr Flexibilität erhalten.

Wenn der Autor der Website Code von Drittanbietern in dieselbe JS-VM laden muss und dazu den eingebauten JS-Parser verwenden möchte, kann er die Eigenschaften jederzeit sichern, indem er sie vor dem Laden des Codes von Drittanbietern auf nicht konfigurierbar setzt.

Pacerier
quelle