Pourquoi pouvons-nous supprimer certaines propriétés intégrées de l'objet global?

12

Je lis es5 ces jours-ci et je trouve que l'attribut [[configurable]] dans certaines propriétés intégrées de l'objet global est défini sur true, ce qui signifie que nous pouvons supprimer ces propriétés.

Par exemple:

la méthode join de l'objet Array.prototype possède des attributs

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

Nous pouvons donc facilement supprimer la méthode de jointure pour Array comme:

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

L'alerte s'affichera undefineddans mon chrome 17, firefox 9, c'est-à-dire 10, voire ie6;

Dans Chrome 15 et safari 5.1.1, l'attribut [[configurable]] est défini sur true et le résultat de la suppression est également vrai, mais le résultat final l'est toujours function(){[native code]}. On dirait que c'est un bug et que le chrome le corrige.

Je ne l'avais pas remarqué auparavant. À mon avis, la suppression des fonctions intégrées dans le code de l'utilisateur est dangereuse et entraînera autant de bogues lorsque vous travaillez avec d'autres, alors pourquoi ECMAScript prend-il cette décision?

démixer
la source
Les réponses multiples louent la possibilité de personnaliser la fonctionnalité intégrée en supprimant les propriétés, mais cette approche n'est nécessaire que parce que la fonctionnalité est câblée dans des variables globales au lieu d'utiliser DI. Il semble que la personnalisation en supprimant des propriétés soit un hack autour d'une conception fondamentalement mauvaise. Par exemple, si vous devez pouvoir modifier l'analyseur JSON, vous pouvez écrire du code qui prend un analyseur JSON en entrée.
Rétablir Monica

Réponses:

2

J'aurais tendance à être d'accord avec vous, mais d'un autre côté, je viens de trouver une situation où j'en avais besoin delete JSON.stringifydans certaines circonstances en raison d'un bogue dans Firefox 3.5 . J'étais certainement heureux de la possibilité de créer des patchs de singe là-bas.

N3dst4
la source
Pourquoi ne pas simplement l'emporter?
démixez
2
Parce que la prochaine chose qui se produit est que JSON2.js est chargé, qui détecte la présence de JSON.stringifyet l'injecte si nécessaire. Toutes mes excuses, je n'ai pas expliqué cela dans ma réponse.
N3dst4
Vous pouvez donc également modifier le code source de JSON2.js, lol
démixez
C'est une mauvaise idée de modifier des bibliothèques tierces car vous ne pouvez pas les mettre à niveau sans copier toutes vos modifications.
N3dst4
1

Configurable ne concerne pas la suppression.

Il s'agit de la possibilité de remplacer une valeur en lecture seule.

C'est un outil très puissant et les valeurs non configurables sont frustrantes si vous ne pouvez pas les supprimer.

J'ai eu pas mal de cas où j'avais besoin de corriger un bug obscur ou d'injecter des fonctionnalités légèrement différentes (interception, journalisation). Pour ce faire, vous devez remplacer la valeur.

Exemple:

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 */

L'idée est que si vous pouvez supprimer des propriétés, vous avez plus de contrôle de méta-programmation. Si vous ne pouviez pas les supprimer, vous seriez simplement ennuyé par la langue.

Il n'y a aucune bonne raison de rendre les propriétés non effaçables autres que d'ennuyer les gens.

Raynos
la source
1
L'attribut [[inscriptible]] contrôle la possibilité de modifier la valeur. Dans ES5: [[inscriptible]] Booléen Si faux, les tentatives par le code ECMAScript pour modifier l'attribut [[Value]] de la propriété en utilisant [[Put]] échouent . [[Configurable]] Boolean Si la valeur est false, les tentatives de suppression de la propriété, de modification de la propriété en tant que propriété d'accesseur ou de modification de ses attributs (autres que [[Value]]) échouent.
démixez
@demix Oui, c'est exact ...
Raynos
0

La suppression des fonctions intégrées dans le code de l'utilisateur est dangereuse

Bien au contraire. Autoriser la personnalisation est une bonne chose car cela permet aux auteurs de sites Web d'avoir plus de flexibilité.

Si l'auteur du site Web doit charger du code tiers dans la même machine virtuelle JS et souhaite utiliser l'analyseur JS intégré pour le faire, il peut toujours sécuriser les propriétés en les définissant sur non configurables avant de charger le code tiers.

Pacerier
la source