2012-07-17 11 views
6

Questa domanda è legata alla What are the best practices to follow when declaring an array in Javascript?È possibile aggiungere una funzione a un array JavaScript dirottato?


Diciamo un cliente, chiamiamoli "D. B. Cooper", ha un primo requisito che il seguente codice deve essere eseguito prima di qualsiasi altro codice JavaScript:

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

Inoltre, Cooper richiede che le funzioni personalizzate debbano essere aggiunte all'oggetto Array integrato (non quello dirottato). Per esempio, se è stato Array unhijacked, questo sarebbe essere fatto con:

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

Che sarebbe permettersi:

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

Tuttavia, questo non è compatibile con il primo requisito. Quindi, come puoi soddisfare al meglio entrambi i requisiti di D. B. Cooper?

Nota: D.B. anche scritto a test fiddle per aiutare a garantire che le soluzioni soddisfino i suoi requisiti ... che ragazzo!


Aggiornamento: Per quelli di voi che come una sfida: per favore cercate di trovare una soluzione cross-browser unhijackable a questo problema. Ad esempio, here's un caso di test ancora più dirottato (grazie per la riformattazione di questo Bergi) che dirotta Array, Object, Array.prototype.constructor e Object.prototype.constructor. Finora, sembra che ci possa essere una soluzione specifica per il browser (vedi Bergi's comment on his answer e facci sapere se trovi un modo per dirottarlo in FF), ma non è chiaro a questo punto se c'è un cross-browser soluzione a questo.

+2

il formato di questa domanda dovrebbe essere richiesta materiale di studio per nuovi poster su SO – rjz

+2

Inviare il documento dei requisiti di nuovo al DB Cooper e insistere su casi di utilizzo per ogni esigenza. :) – Quentin

+0

@Quentin: Se riesci a trovarlo, sarebbe una buona opzione :) – Briguy37

risposta

2

Qualunque sia la vostra Array funzione/costruttore è, la sintassi letterale per gli array genererà sempre array "reali" con il loro [[prototype]] impostato all'oggetto prototipo di matrice nativo (una volta, questo was a security vulnerability). Quindi, è sempre possibile accedere che utilizzando

Object.getPrototypeOf([]) 

anche se Array o [].constructor sono dirottato.(Will, naturalmente, non funziona quando Object viene dirottato, allora ottiene è davvero complicato)

(Brought D.B. down!)


Se si desidera utilizzare una soluzione alternativa, in FF la seguente riga funziona sempre (e non è hijackable):

[].__proto__.coolCustomFunction = coolCustomFunction; 
+0

Interessante! Ho deciso di provare a dirottare il costruttore dell'oggetto array: '[] .constructor.prototype.constructor = ..', e questo ha causato il fallimento della soluzione di Torsten. Quindi, ho dirottato Object e questo ha causato il fallimento della tua soluzione, ma funziona con '({}). Constructor'. Poi ho dirottato il costruttore dell'oggetto Object: '({}). Constructor.prototype.constructor = ..' che ha causato il fallimento di tutto. A quel punto, mi sono bloccato, quindi non ho trovato una soluzione non-hijackable a questo ancora :) Ecco un violino aggiornamento: http://jsfiddle.net/briguy37/yXPJ8/8/ – Briguy37

+1

Che era esattamente la mia linea di pensiero :-) Tuttavia, ho [ristretto il tuo violino dirottato pesante] (http://jsfiddle.net/yXPJ8/9/) per essere più leggibile. Ora, puoi usare solo "__proto__" non standard in FF (irriconoscibile, credo) – Bergi

+0

Molto bello, non vedo neanche un modo per dirottarlo in FF! Sono ancora interessato a vedere se il suggerimento di @ Torsten di ottenere il costruttore da un nuovo oggetto finestra o da un altro metodo possa portare a una soluzione non dirottata per il browser. – Briguy37

1

Sì ... hai appena fatto ... ma si è creato l'array usando [] .. se si utilizza new Array() che funziona bene ...

See example here

+2

Siamo spiacenti, questo non soddisfa il caso di test. Non sei autorizzato a modificarlo. – Briguy37

+0

@ Briguy37 quindi non può - non è possibile sovrascrivere la funzione '[]' - questo punta a un costruttore interno – ManseUK

+0

Questo potrebbe essere il caso. Tuttavia, se modifichi il prototipo di 'Array' per aggiungere una funzione prima di dirottarla, puoi usare quella funzione su un oggetto creato con' [] '. Quindi, mi chiedevo se ci fosse un modo per farlo dopo che Array era stato dirottato. – Briguy37

3

Dal Array non è necessariamente uguale a [].constructor , è possibile utilizzare [].constructor per fare riferimento alla funzione Array originale poiché questo è cablato e Array = function(){} non lo modificherà.

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

La tua prima soluzione rende D.B. felice :) (il secondo violerebbe il suo primo requisito) – Briguy37

+0

Ok, ho saltato il bit "prima di ogni altro". ;) –

+0

Cosa succede se 'arrayProto.constructor = wrongArray'? – Bergi

Problemi correlati