javascript some - aggiunta di funzioni personalizzate in Array.prototype




js cast (5)

Hai aumentato i tipi generici per così dire. Probabilmente hai sovrascritto alcune funzionalità di lib e per questo ha smesso di funzionare.

Supponiamo che alcune librerie che utilizzi estendano l'array con la funzione Array.remove (). Dopo il caricamento della lib, si aggiunge remove () al prototipo di Array ma con le proprie funzionalità. Quando lib chiamerà la tua funzione, probabilmente funzionerà in un modo diverso come previsto e interromperà l'esecuzione ... Ecco cosa sta succedendo qui.

Stavo lavorando su un'applicazione asp.net abilitata per AJAX. Ho appena aggiunto alcuni metodi a Array.prototype come

Array.prototype.doSomething = function(){
   ...
}

Questa soluzione ha funzionato per me, essendo possibile riutilizzare il codice in un modo "carino".

Ma quando ho provato a lavorare con l'intera pagina, ho avuto dei problemi .. Avevamo alcuni estensori ajax personalizzati e hanno iniziato a comportarsi come imprevisti: alcuni controlli venivano visualizzati "non definiti" attorno al suo contenuto o valore.

Quale potrebbe essere la causa? Mi manca qualcosa sulla modifica del prototipo degli oggetti standard?

Nota: sono abbastanza sicuro che l'errore inizi quando modifico il prototipo per Array. Dovrebbe essere compatibile solo con IE.


Mentre il potenziale per lo scontro con altri bit o 'code l'override di una funzione su un prototipo è ancora un rischio, se vuoi farlo con le moderne versioni di JavaScript, puoi usare il metodo Object.defineProperty, disattivando il bit enumerabile, per esempio

// functional sort
Object.defineProperty(Array.prototype, 'sortf', {
    enumerable: false,
    value: function(compare) { return [].concat(this).sort(compare); }
});

La modifica dei prototipi di oggetti incorporati può essere una cattiva idea in generale, perché ha sempre il potenziale per scontrarsi con altri codici sulla stessa pagina.

Nel caso del prototipo dell'oggetto Array, è un'idea particolarmente negativa, perché ha il potenziale di interferire con qualsiasi parte di codice che itera sui membri di qualsiasi array, ad esempio con for .. in .

Per illustrare usando un esempio (preso in prestito da here ):

Array.prototype.foo = 1;

// somewhere deep in other javascript code...
var a = [1,2,3,4,5];
for (x in a){
    // Now foo is a part of EVERY array and 
    // will show up here as a value of 'x'
}

Sarebbe meglio per te creare il tuo tipo di costruttore di oggetti completo con la funzione doSomething, piuttosto che estendere l'array integrato.

Modifica: per ripetere ciò che ho inserito in un commento:

L'inverso è vero - dovresti evitare per..in caso in cui n00b abbia modificato il prototipo di Array, e dovresti evitare di modificare il prototipo di Array nel caso in cui n00b abbia usato per..in su un array. ;)

Inoltre, esiste ora Object.defineProperty come un modo generale di estendere i prototipi di oggetti senza che le nuove proprietà siano enumerabili, anche se non lo Object.defineProperty ancora come giustificazione per estendere i tipi built-in , perché anche oltre for..in c'è ancora il potenziale per altri conflitti con altri script. Considera qualcuno che biforca il codice e quindi inserisce entrambe le versioni nella stessa pagina: il tuo miglioramento personalizzato per l'oggetto Array continuerà a funzionare come ti aspetti?


In generale, fare scherzi con gli oggetti javascript di base è una cattiva idea. Non sai mai cosa potrebbero aspettarsi eventuali librerie di terze parti e cambiare gli oggetti principali in javascript le cambia per tutto.

Se usi Prototype è particolarmente brutto perché il prototipo ha dei problemi con l'ambito globale ed è difficile dire se stai andando a scontrarsi o meno. In realtà modificare le parti principali di qualsiasi lingua è di solito una cattiva idea anche in javascript.

(Lisp potrebbe essere la piccola eccezione lì)


Il primo esempio è una dichiarazione di funzione:

function abc(){}

Il secondo esempio è un'espressione di funzione:

var abc = function() {};

La differenza principale è come vengono issati (sollevati e dichiarati). Nel primo esempio, viene issata l'intera dichiarazione di funzione. Nel secondo esempio viene issata la var 'abc', il suo valore (la funzione) sarà indefinito e la funzione stessa rimarrà nella posizione in cui è stata dichiarata.

Per dirla semplicemente:

//this will work
abc(param);
function abc(){}

//this would fail
abc(param);
var abc = function() {}

Per studiare di più su questo argomento ti consiglio vivamente questo link





javascript arrays internet-explorer