¿Por qué podemos eliminar algunas propiedades integradas del objeto global?

12

Estoy leyendo es5 en estos días y encuentro que el atributo [[configurable]] en algunas propiedades integradas del objeto global está establecido en verdadero, lo que significa que podemos eliminar estas propiedades.

Por ejemplo:

el método de combinación del objeto Array.prototype tiene atributos

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

Por lo tanto, podemos eliminar fácilmente el método de combinación para Array como:

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

La alerta se mostrará undefineden mi cromo 17, firefox 9, es decir 10, incluso ie6;

En Chrome 15 y safari 5.1.1, el atributo [[configurable]] se establece en verdadero y el resultado de eliminación también es cierto, pero el resultado final aún lo es function(){[native code]}. Parece que esto es un error y el cromo lo soluciona.

No lo he notado antes. En mi opinión, eliminar las funciones integradas en el código del usuario es peligroso y generará tantos errores al trabajar con otros. Entonces, ¿por qué ECMAScript toma esta decisión?

demix
fuente
Las respuestas múltiples elogian la capacidad de personalizar la funcionalidad incorporada eliminando propiedades, pero este enfoque solo es necesario porque la funcionalidad está cableada en variables globales en lugar de usar DI. Parece que la personalización eliminando propiedades es un truco en torno a un diseño fundamentalmente malo. Por ejemplo, si necesita poder cambiar el analizador JSON, puede escribir código que tome un analizador JSON como entrada.
Vuelva a instalar a Monica el

Respuestas:

2

Tendería a estar de acuerdo con usted, pero por otro lado, acabo de encontrar una situación en la que lo necesitaba delete JSON.stringifyen ciertas circunstancias debido a un error en Firefox 3.5 . Ciertamente me alegré de la capacidad de parchear monos incorporados allí.

N3dst4
fuente
¿Por qué no lo anulas?
demix
2
Porque lo siguiente que sucede es que se carga JSON2.js, que detecta la presencia JSON.stringifye inyecta si es necesario. Disculpas, no expliqué eso en mi respuesta.
N3dst4
Así que también puedes modificar el código fuente de JSON2.js, lol
demix
Es una mala idea modificar las bibliotecas de terceros porque no puede actualizarlas sin copiar todos los cambios.
N3dst4
1

Configurable no se trata de eliminación.

Se trata de la capacidad de reemplazar un valor de solo lectura.

Es una herramienta muy poderosa, y los valores no configurables son frustrantes si no puede eliminarlos.

He tenido bastantes casos en los que necesitaba corregir un error oscuro o inyectar funcionalidades ligeramente diferentes (intercepción, registro). Hacer eso requiere reemplazar el valor.

Ejemplo:

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

La idea es que si puede eliminar propiedades, tiene más control de meta programación. Si no pudieras eliminarlos, entonces te molestaría el idioma.

No hay una buena razón para hacer que las propiedades no sean delegables, aparte de molestar a las personas.

Raynos
fuente
1
El atributo [[editable]] controla la capacidad de cambiar el valor. En ES5: [[Escribible]] Booleano Si es falso, los intentos por el código ECMAScript para cambiar el atributo [[Valor]] de la propiedad usando [[Put]] no tendrán éxito . [[Configurable]] Booleano Si es falso, los intentos de eliminar la propiedad, cambiar la propiedad para que sea una propiedad de acceso o cambiar sus atributos (que no sean [[Valor]]) fallarán.
demix
@demix Sí, eso es correcto ...
Raynos
0

..eliminar funciones incorporadas en el código del usuario es peligroso

Todo lo contrario. Permitir la personalización es bueno porque permite a los autores de sitios web tener más flexibilidad.

Si el autor del sitio web necesita cargar código de terceros dentro de la misma JS VM y desea utilizar el analizador incorporado de JS para hacerlo, siempre puede proteger las propiedades configurándolas como no configurables antes de cargar el código de terceros.

Pacerier
fuente