En primer lugar, quiero decir que sé que extender los métodos globales no es una buena práctica, pero hay situaciones en las que un desarrollador necesita evitar la duplicación de objetos debido al tamaño u otras razones, y las funciones globales pueden ayudar mucho en tales situaciones. .(al menos eso es lo que creo)
Saqué este tema porque me parece extraño que este "error" (ejemplo abajo) todavía exista en JavaScript, porque si no me equivoco hace unos 5 años necesitaba atravesar un objeto window con un bucle y terminé encontrándolo , pero como ha pasado tanto tiempo y todavía existe, creo que podría ser normal para Object.prototype
¿Alguien puede decirme si es un error olvidado o es algo normal? ¿No se puede explotar esto como inyección de código junto con esto ?
Object.prototype.foo = function(){ for(index in this) console.log(index) } var A = [1,2,3]; //returns a non-iterable index at the end A.foo(); function bar(attr){ var B = {a:1, b:2,c:3} for(index in B) console.log(index); for(index in attr) console.log(index); } //all the 'in' iterations will start printing the index value at the end bar([1,2,3,4,5]); for(index in {x:1, y:2,z:3}) console.log(index);Esto es completamente normal y esperado.
for..in itera sobre todas las propiedades enumerables del objeto en cuestión. Luego hace lo mismo con el prototipo interno de ese objeto, y así sucesivamente, hasta que llega al comienzo de la cadena de prototipos (que suele ser Object.prototype ).
Si coloca una propiedad enumerable en Object.prototype , entonces cualquier objeto (que herede de Object.prototype ) que itere con for..in eventualmente iterará sobre esa propiedad que agregó.
¿No se puede explotar esto como inyección de código junto con esto?
Supongo que el código malicioso puede modificar Object.prototype y hacer muchas otras cosas desagradables, así que tenga cuidado de no ejecutar nada que no sea confiable.
La contaminación accidental del prototipo (incluso ocasionalmente por la entrada del usuario) no es un problema poco común con el que a veces se encuentran las bibliotecas. Una buena regla general es usar nombres de clave estáticos en todas partes: si necesita algo dinámico, use un Mapa en lugar de un objeto.
El comportamiento que estás observando es normal. Las propiedades definidas en Object.prototype serán prototipo vinculado por sus instancias. El for..in sobre todas las propiedades enumerables de un objeto, ya sea propio o heredado.
Puede acceder a foo en A.__proto__.__proto__.foo .
A es una instancia de Array[] , que es una instancia de Object{} global.
El atributo de propiedad enumerable define si la propiedad es seleccionada por Object.assign() o por el operador de extensión. Para las propiedades que no son de símbolo, también define si se muestra en un bucle for...in y Object.keys() o no.
Puede definir la propiedad como un atributo innumerable configurando el indicador enumerable en false .
Object.defineProperty(Object.prototype, "foo", { value: function(){ for(index in this) console.log(index); }, configurable: true, enumerable: false }); Puede congelar el Object.prototype de la siguiente manera:
Object.freeze(Object.prototype); Object.freeze(Object);para evitar que los atacantes la contaminen.