2012-07-17 6 views
6

Esta pregunta se relaciona con What are the best practices to follow when declaring an array in Javascript?¿Se puede agregar una función a una matriz de JavaScript secuestrada?


Digamos que un cliente, llamémosles "D. B. Cooper", tiene una primera exigencia de que el siguiente código se debe ejecutar antes de que cualquier otro tipo de código JavaScript:

Array = function(){ 
    alert('Mwahahahaha'); 
}; 

Por otra parte, Cooper requiere que se agreguen funciones personalizadas al objeto Array incorporado (no el que se secuestró). Por ejemplo, si se Array unhijacked, esto se haría con:

Array.prototype.coolCustomFunction = function(){ 
    alert('I have ' + this.length + ' elements! Cool!'); 
}; 

lo que otorgaría:

var myArray = []; 
myArray.coolCustomFunction(); 

Sin embargo, esto no es compatible con el primer requisito. Por lo tanto, ¿cómo se puede cumplir mejor con los requisitos de D. B. Cooper?

Nota: D.B. incluso escribió a test fiddle para ayudar a asegurarse de que las soluciones cumplan con sus requisitos ... ¡qué hombre!


Actualización: Para aquellos de ustedes que les gusta un desafío: por favor, tratar de encontrar una solución multi-navegador unhijackable a este problema. Por ejemplo, here's un caso de prueba aún más secuestrado (gracias por reformatear este Bergi) que secuestra Array, Object, Array.prototype.constructor y Object.prototype.constructor. Hasta el momento, parece que puede haber una solución específica para este navegador (consulte Bergi's comment on his answer, y avísenos si encuentra una forma de secuestrarlo en FF), pero no está claro en este momento si hay un navegador cruzado solución a esto.

+2

el formato de esta pregunta debe ser material de estudio necesario para los nuevos carteles en SO – rjz

+2

Enviar el documento de requisitos de vuelta a DB Cooper e insistir en los casos de uso para cada demanda. :) – Quentin

+0

@Quentin: Si puede encontrarlo, esa sería una buena opción :) – Briguy37

Respuesta

2

Sea cual sea su Array función/constructor es, la sintaxis literal para matrices siempre generará matrices "reales" con su [[Prototype]] ajustado al objeto prototipo gama nativa (una vez, esto was a security vulnerability). Por lo tanto, siempre se puede acceder a que mediante el uso

Object.getPrototypeOf([]) 

incluso si Array o [].constructor son secuestrados.(Por supuesto, no funciona cuando Object es secuestrado, entonces llegar muy complicado)

(Brought D.B. down!)


Si desea utilizar una solución, in FF la siguiente línea siempre funciona (y no es hijackable):

[].__proto__.coolCustomFunction = coolCustomFunction; 
+0

¡Interesante! Decidí intentar secuestrar el constructor del objeto array: '[] .constructor.prototype.constructor = ..', y eso hizo que fallara la solución de Torsten. Luego, secuestré Object y eso causó que tu solución fallara, pero funciona con '({}). Constructor'. Luego secuestré el constructor del objeto Object: '({}). Constructor.prototype.constructor = ..' que hizo que todo fallara. En ese momento, estoy atascado, así que no he encontrado una solución no secuestrable para esto todavía :) Aquí hay un violín actualizado: http://jsfiddle.net/briguy37/yXPJ8/8/ – Briguy37

+1

Esa era exactamente mi línea de pensamiento :-) Sin embargo, he [reconstruido tu violín fuertemente secuestrado] (http://jsfiddle.net/yXPJ8/9/) para que sea más legible. Ahora, solo puedes usar '__proto__' no estándar en FF (imposible de identificar, creo) – Bergi

+0

¡Muy bien, tampoco veo una forma de secuestrar eso en FF! Todavía estoy interesado en ver si la sugerencia de @Torsten para obtener el constructor de un nuevo objeto de ventana u otro método podría conducir a una solución no secuestrable entre navegadores. – Briguy37

1

Sí ... que acabas de hacer ... pero se crea la matriz mediante [] .. si utiliza new Array() funciona bien ...

See example here

+2

Disculpe, eso no cumple con el caso de prueba. No puedes editarlo. – Briguy37

+0

@ Briguy37 no puede sobrescribir la función '[]' - esto apunta a un constructor interno – ManseUK

+0

Ese puede ser el caso. Sin embargo, si modifica el prototipo de 'Array' para agregar una función antes de secuestrarlo, puede usar esa función en un objeto creado con' [] '. Por lo tanto, me preguntaba si había una manera de hacer esto después de que Array fuera secuestrado. – Briguy37

3

Desde Array no es necesariamente igual a [].constructor , puede usar [].constructor para referirse a la función de matriz original, ya que está cableada y Array = function(){} no la alterará.

Array = function() { alert("foo")}; 

// this will always point to the original Array 
[].constructor.prototype.foo = "bar"; 

var myArray = [0, 1]; 
alert(myArray.foo) // alerts "bar" 

http://jsfiddle.net/yXPJ8/5/

+0

Su primera solución hace D.B. feliz :) (el segundo violaría su primer requisito) – Briguy37

+0

De acuerdo, se perdió el bit "antes que cualquier otro". ;) –

+0

¿Qué sucede si 'arrayProto.constructor = wrongArray'? – Bergi

Cuestiones relacionadas