Comprensione delle variabili di applicazione Quando ricorsioneCapire il comportamento di variabili quando Attuazione ricorsione Problema che si desidera implementare la ricorsione in JavaScript, e voi dovete anche capire come si comporteranno le variabili in quelle circostanze. Teoria in JavaScript, non è necessario dichiarare il tipo di variabile, o addirittura dichiarare la variabile. Ad esempio, il seguente codice funziona perfettamente: if (contatore == 1) ( buffer = "È contro 1";) document.getElementById ( "risultato"). InnerHTML = buffer; La variabile buffer non è stata dichiarata prima del blocco, se nel codice precedente. L'ultima riga del codice usa il buffer variabile per assegnare la proprietà innerHTML. Questo tipo di dichiarazione è problematico perché il buffer potrebbe essere indefinito. JavaScript non citare questo come un errore, e innerHTML verrà assegnato il valore undefined. Questo esempio dimostra che le variabili in JavaScript possono comportarsi in modi che un programmatore con un background Java o C #, non può essere abituati. Il focus di questa ricetta è capire come una variabile si comporta in contesti diversi. Un contesto esempio è l'implementazione della ricorsione in JavaScript. Solution due funzioni, ad esempio che implementano la ricorsione in JavaScript seguire. Fonte: / website / ROOT / ajaxrecipes / javascript / variablebehavior.html funzione RecursionGlobal (counter) (info ( "RecursionGlobal localCounter ()", typeof (localCounter)); localCounter = counter; info ( "RecursionGlobal localCounter ()", localCounter); se (localCounter <3) (RecursionGlobal (localCounter + 1);)) function RecursionLocal (counter) (info ( "RecursionLocal localCounter ()", typeof (localCounter)); var counter = localCounter; info ( "RecursionLocal localCounter ()", localCounter); if (localCounter <3) (RecursionLocal (localCounter + 1);)) L'esempio mostra due metodi: RecursionGlobal e RecursionLocal. Tra i due metodi c'è una sola differenza, come illustrato nel codice in grassetto: la parola chiave var JavaScript. L'unica parola chiave var è la variazione su come la variabile localCounter è memorizzato. Il comportamento di entrambi i metodi, quando eseguito è identica e genera lo stesso risultato. Si può pensare a prima vista che la parola chiave var non serve qualsiasi scopo. Ma la parola chiave var ha uno scopo, che è illustrato eseguendo il seguente programma: Info: recursion_global *** *** Started Info: RecursionGlobal () localCounter undefined Info: RecursionGlobal () localCounter 1 Info: RecursionGlobal () localCounter numero Info: RecursionGlobal () localCounter 2 Info: RecursionGlobal () localCounter numero Info: RecursionGlobal (localCounter 3) Info: recursion_local *** *** Started Info: RecursionLocal () localCounter undefined Info: RecursionLocal () localCounter 1 Info: RecursionLocal () localCounter undefined Info: RecursionLocal () localCounter 2 Info: RecursionLocal () localCounter undefined Info: RecursionLocal localCounter () 3
Si noti che quando la funzione RecursionGlobal esegue, il tipo di localCounter per il primo invito è indefinito, e, successivamente, è il numero. Al contrario, quando la funzione RecurisonLocal è chiamata, il tipo di localCounter non è definito per ciascuno e per ogni chiamata. Ciò significa che var serve allo scopo di dichiarare una variabile che è locale per l'ambito da cui è dichiarata. Se la variabile non è associato a una parola chiave var, allora la variabile è dichiarata in ambito globale. Nel caso della creazione di un ciclo di ricorsione, sarà necessario utilizzare la parola chiave var per tutti i casi, altrimenti ci potrebbe essere la corruzione dei dati. Il seguente esempio illustra come invertire il contenuto di una pila utilizzando la ricorsione. Quando si utilizza la ricorsione, a volte si dovranno dichiarare parametri di funzione che non servono se non come valori di riferimento. Fonte: / website / ROOT / ajaxrecipes / javascript / variablebehavior.html funzione RecursiveStackOldWay (arrayToProcess, processedArray) (info ( "RecursiveStackOldWay", "---> Start "); info (" RecursiveStackOldWay "," profondità Recursive = "+ (processedArray. lunghezza + 1)); processedArray.push (arrayToProcess.pop ()); if (arrayToProcess.length> 0) (RecursiveStackOldWay (arrayToProcess, processedArray);) info ( "RecursiveStackOldWay", "---> End ");) arrayToProcess var = new Array (); arrayToProcess.push ( "valore1"); arrayToProcess.push ( "valore2"); processedArray var = new Array () RecursiveOldWayStack (arrayToProcess, processedArray); Qui, la funzione RecursiveStackOldWay ha due parametri: arrayToProcess e processedArray. Il primo parametro, arrayToProcess, è la matrice che verrà invertita. Il secondo parametro, processedArray, è la destinazione dello stack. La destinazione stack deve essere trascinato come un parametro per ogni ricorrenza, in modo che la funzione può mettere la pila da qualche parte. Il chiamante è responsabile per istanziare la destinazione stack e passandolo alla funzione ricorsiva. Spesso, però, durante la creazione di funzioni ricorsive , è necessario chiamare la funzione di alcuni parametri che sono definiti in alto a prima richiesta a livello. Questi parametri non hanno nulla a che fare con la chiamata iniziale, ma la parte superiore di primo livello chiamata deve dichiarare loro (processedArray). In poche parole, il problema è che quando si chiama una funzione ricorsiva, è necessario inizializzare una serie di variabili che vengono poi utilizzati dalla ricorsione. Nell'esempio, l'inizializzazione è una responsabilità del chiamante. La soluzione funziona, ma è lungi dall'essere ottimale, perché lo sviluppatore ha bisogno di capire come certi parametri di funzione, anche se non possono essere utilizzate dal chiamante. Un'altra soluzione è quella di creare una funzione wrapper per la ricorsione che inizializza i parametri e poi chiama la ricorsione. La funzione wrapper funzionerà, ma ora il programmatore deve mantenere la funzione di ricorsione e la funzione wrapper. Javascript offre una terza soluzione: lasciare che la funzione di ricorsione inizializzazione. La domanda è: come fa la funzione di ricorsione sapere che viene chiamato per la prima volta? In un linguaggio tradizionale di programmazione come Java o C #, un parametro booleano sarebbero definiti e impostare a true per indicare la prima chiamata, e false per indicare qualsiasi chiamata successiva. La soluzione JavaScript non richiede una bandiera o un indicatore, perché i parametri stessi sono indicatori. Per esempio, immaginate se la funzione di implementazione RecursiveOldWayStack rimane così com'è e il codice che chiama RecursiveOldWayStack somiglia quanto segue: arrayToProcess var = new Array (); arrayToProcess.push ( "valore1"); arrayToProcess.push ( "valore2"); processedArray var = RecursiveOldWayStack (arrayToProcess); In fase di attuazione, non modificato, il chiamante è responsabile per istanziare la destinazione stack. Che la responsabilità è stata delegata alla funzione RecursiveOldWayStack. Però, sorge un problema, perché RecursiveOldWayStack bisogno per inizializzare e avviare la ricorsione. La soluzione utilizzata da JavaScript è quello di determinare se il secondo parametro è definito, come illustrato nella seguente funzione modificati, detti RecursiveStack. Fonte: / website / ROOT / ajaxrecipes / javascript / variablebehavior.html funzione RecursiveStack (arrayToProcess, processedArray) (info ( "RecursiveStack", "---> Start "); if (typeof (processedArray) == "undefined") ( info ( "RecursiveStack", "iniziale"); processedArray = new Array (); RecursiveStack (arrayToProcess, processedArray); info ( "RecursiveStack", "---> End "); return processedArray; )else (info ( "RecursiveStack", "profondità Recursive =" + (processedArray.length + 1)); processedArray.push (arrayToProcess.pop ()); if (arrayToProcess.length> 0) (RecursiveStack (arrayToProcess, processedArray); info) ( "RecursiveStack", "---> End "); return;)) In sede di attuazione la modifica, la funzione RecursiveStack implementa un aspettativa. L'aspettativa è che se la funzione viene chiamata con un solo parametro, allora è un chiamante fare la prima chiamata della ricorsione, altrimenti, una ricorsione che sta accadendo. L'attesa di sapere se un primo invito che sta accadendo è determinato dal codice in grassetto. Se il secondo parametro, processedArray, non è definito, allora la funzione ricorsiva si inizializza e inizia la ricorsione. Se il secondo parametro è definito, quindi si presuppone una ricorsione che sta accadendo, e la funzione dovrà elaborare i dati in quanto tale. Prima di continuare, potrebbe aver catturato il fatto che RecursiveStack dispone di due parametri, ma viene chiamato con uno. Prima ho parlato di aspettative e che il chiamante deve passare due parametri. Questo esempio non dire che il chiamante non ha bisogno di passare due parametri, ma piuttosto l'esempio dice che se il chiamante non passa due parametri, la funzione ha la capacità di compensare. La stessa funzione può essere utilizzata per l'inizializzazione e ricorsione sulla base di una previsione. Se, tuttavia, un chiamante definisce il secondo parametro, significa che il chiamante ha assunto la responsabilità di attuare l'inizializzazione. Con un chiamante definito l'inizializzazione, RecursiveStack non si esibirà in una inizializzazione e passare direttamente alla funzionalità di ricorsione. Il vantaggio di questa soluzione è che si dispone di una funzione polivalente senza dover definire in modo esplicito una funzione wrapper. Potreste pensare: "Naturalmente questo è possibile utilizzando un linguaggio come Java o C # utilizzando le funzioni di sovraccarica." Sì, è possibile utilizzando le funzioni di sovraccarica, ma come detto in precedenza, una funzione di sovraccarico è una funzione wrapper che chiama l'effettiva esecuzione , vale a dire due funzioni devono essere scritte e mantenute. In JavaScript, tutto può essere avvolto in un self-contained funzione. Ora che avete attuato la ricorsione e conoscere la differenza tra una variabile di ambito locale e una variabile globale ambito, la prossima domanda è, cosa succede se ci sono due variabili con il lo stesso nome? Immaginate la definizione di una variabile in un ambito locale, che esiste in un ambito globale, ciò che accade al livello globale e locale ambito dichiarazioni di variabili? Il codice seguente mostra come una variabile è definita a livello globale in una funzione e quindi si fa riferimento a un'altra funzione. Fonte: / website / ROOT / ajaxrecipes / javascript / variablebehavior.html GlobalScope function () (info ( "GlobalScope scopedVariable ()", typeof (scopedVariable)); scopedVariable = "GlobalScope"; info ( "GlobalScope scopedVariable ()", "scopedVariable =" + + scopedVariable ➥ "type =" + typeof (scopedVariable));) TestScope function () (info ( "OtherScope (scopedVariable)", "scopedVariable = "+ scopedVariable + "Type =" + ➥ typeof (scopedVariable));) scopedVariable è definito in GlobalScope e di riferimento nel TestScope. Poiché non vi è alcuna var-based dichiarazione di scopedVariable in GlobalScope, scopedVariable è messo in ambito globale. Running TestScope dopo GlobalScope si tradurrà in scopedVariable essere definito globalmente, come illustrato nella seguente output generato: Info: GlobalScope () scopedVariable undefined Info: GlobalToLocalScope (scopedVariable) scopedVariable type = GlobalScope = Info stringa: TestScope (scopedVariable) scopedVariable type = GlobalScope = stringa In output generato, GlobalScope si chiama, e all'inizio della funzione di implementazione, scopedVariable non è definito. Allora scopedVariable viene assegnato un buffer, e l'output generato indica che scopedVariable non è indefinito e fa riferimento a una stringa. Calling TestScope dimostra che scopedVariable è globale e viene assegnato un buffer. Consideriamo ora lo stesso esempio, se una variabile globale ambito è dichiarato nuovamente come un variabile locale utilizzando la parola chiave var. Fonte: / website / ROOT / ajaxrecipes / javascript / variablebehavior.html funzione AlwaysLocalScope () (info ( "GlobalToLocalScope (scopedVariable)", typeof (scopedVariable)); scopedVariable = "AlwaysLocalScope"; info ( "GlobalToLocalScope (scopedVariable)", "scopedVariable = "+ + scopedVariable ➥" type = "+ typeof (scopedVariable)); var scopedVariable;) In funzione di implementazione, scopedVariable viene assegnato un buffer che non utilizza la parola chiave var. Così, scopedVariable è dichiarata a livello mondiale campo di applicazione. O almeno questo è ciò che si è portati a credere. Ciò che accade è che la variabile è dichiarata a livello locale, perché l'ultima istruzione della funzione (in grassetto) dichiara la variabile scopedVariable di essere locali. Può sembrare strano che una variabile è dichiarata locali se da qualche parte nella funzione di var parola chiave viene utilizzata. Diventa ancora più strane, nel senso che se la parola chiave var è utilizzato in un blocco di decisione che non viene mai eseguito, la variabile è ancora dichiarata locale. Per illustrare, in primo luogo la funzione AlwaysLocal si chiama e poi TestScope, che genera il seguente output: Info: AlwaysLocalScope () scopedVariable undefined Info: AlwaysLocalScope (scopedVariable) scopedVariable = AlwaysLocalScope = Avvisa tipo stringa: Errore generale (scopedVariable non è definito) Quando la funzione AlwaysLocalScope si chiama, scopedVariable sarà indefinito, significa che esiste nel campo di applicazione, né locale né a livello mondiale. Poi, quando la variabile è assegnato, l'output generato avrà un valore e tipo. Quando la funzione TestScope si chiama, viene sollevata un'eccezione perché scopedVariable non è definito. Ora sapete quando una variabile viene dichiarata in ambito globale e in ambito locale. L'ultimo test è quello di vedere cosa succede quando una variabile è dichiarata sia globale che locale campo di applicazione. La prova è chiamare le funzioni in sequenza: GlobalScope, TestScope, AlwaysLocalScope, e quindi TestScope. Chiamare questa sequenza genera il seguente output: Info: GlobalScope () scopedVariable undefined Info: GlobalScope scopedVariable () scopedVariable type = GlobalScope = Info stringa: TestScope (scopedVariable) scopedVariable type = GlobalScope = Info stringa: AlwaysLocalScope () scopedVariable undefined Info: AlwaysLocalScope (scopedVariable) scopedVariable = AlwaysLocalScope type = string info: TestScope (scopedVariable) scopedVariable type = GlobalScope = stringa In output generato, scopedVariable è dichiarata e assegnata in GlobalScope. La funzione TestScope verifica che scopedVariable esiste. Poi, quando si chiama AlwaysLocalScope, var dichiara che qualsiasi riferimento alla scopedVariable all'interno della funzione è un punto di riferimento delle variabili locali. Quindi, se vi è una variabile definita a livello globale con lo stesso nome, non è accessibile all'interno del campo di applicazione della funzione. Ci sono due modi per fare riferimento a una variabile globale: il riferimento tramite la proprietà finestra o la creazione di una funzione che è esterno alla funzione di esecuzione (il che significa che non è una funzione inline) e assegnando alla variabile globale scope. Quando una variabile non è stato assegnato, il typeof funzione restituisce undefined. Una volta si assegna una variabile, typeof restituisce un altro valore. Se una variabile è definita nel contesto di una funzione, quindi ogni volta che la funzione viene chiamata, la variabile prima di essere assegnati sarà indefinito. A livello globale, una variabile può essere impostata usando l'operatore delete, come segue: eliminare scopedVariable, di solito, l'operatore delete è usato per reimpostare la proprietà di un oggetto. Quando si elimina viene utilizzato con un identificativo, un riferimento variabile globale è soppresso. Non è possibile rimuovere un riferimento a una funzione utilizzando eliminare. Proviamo un'altra variante del campo di applicazione utilizzando il codice dinamico. In JavaScript, utilizzando la funzione eval eseguirà un buffer JavaScript, che mette alla prova quando una variabile sarà considerata portata mondiale e, quando esso sarà considerato ambito locale. La funzione AlwaysLocalScope sarà quindi modificato. Per la prima variante, AlwaysLocalScope avrà una assegnazione dinamica: AlwaysLocalScope function () (info ( "AlwaysLocalScope (scopedVariable)", typeof (scopedVariable)); eval ( "scopedVariable = 'AlwaysLocalScope'");info ( "AlwaysLocalScope (scopedVariable)", "scopedVariable =" + + scopedVariable ➥ "type =" + typeof (scopedVariable)); scopedVariable var;) Il codice modificato è indicato in grassetto, e l'assegnazione di scopedVariable viene eseguito. Utilizzare eval in questo modo non ha alcun effetto, e l'esecuzione dinamica del codice è lo stesso, come se il codice non era stato modificato. Il vantaggio con eval è che si può assegnare un pezzo di codice ad un buffer di testo, e quindi eseguire tale buffer. Il campo di applicazione scopedVariable non è stato modificato, perché la parola chiave var esiste ancora nella dichiarazione di funzione. La dichiarazione, quando analizzati dal processore JavaScript si tradurrà in una dichiarazione delle variabili locali. Un modo per modificare il comportamento locale dichiarazione è quello di incorporare la dichiarazione di variabile in una dichiarazione eval, come illustrato nel codice seguente modifica: AlwaysLocalScope function () (info ( "AlwaysLocalScope (scopedVariable)", typeof (scopedVariable)); eval ( "scopedVariable = 'AlwaysLocalScope'");info ( "AlwaysLocalScope (scopedVariable)", "scopedVariable =" + + scopedVariable ➥ "type =" + typeof (scopedVariable)); eval ( "var scopedVariable;");) Il codice modificato per quanto riguarda il codice AlwaysLocalScope originale è in grassetto. Questa volta, sia l'assegnazione e la dichiarazione di scopedVariable sono dinamici, nel senso che scopedVariable quando viene assegnato sarà trattata come una variabile globale. Ciò è perché quando la prima istruzione eval viene eseguito, non vi è alcuna dichiarazione di scopedVariable, e il runtime JavaScript memorizzerà scopedVariable nello spazio globale. Per modificare il comportamento e dichiarare scopedVariable come una variabile locale, AlwaysLocalScope deve essere modificato uno più tempo , come segue: AlwaysLocalScope function () (info ( "AlwaysLocalScope (scopedVariable)", typeof (scopedVariable)); eval ( "var scopedVariable;"); eval ( "scopedVariable = 'AlwaysLocalScope'");info ( "AlwaysLocalScope (scopedVariable)", "scopedVariable =" + + scopedVariable ➥ "type =" + typeof (scopedVariable));) Nel ultime modifiche apportate, il eval prima è la dichiarazione di scopedVariable utilizzando la parola chiave var. I primi risultati di chiamata eval nella dichiarazione di scopedVariable come una variabile locale. La seconda chiamata eval assegna un valore a scopedVariable, che è ambito come una variabile locale. Quando le variabili che dichiara nel quadro delle funzioni o in ambito globale, a mantenere i seguenti punti in mente: • Ci sono due ambiti in una variabile: locale a una funzione e globale. • Una variabile locale è dichiarata usando la parola chiave var, con l'eccezione è l'uso di var in un contesto globale. L'uso di var, non ha bisogno di essere all'inizio di una funzione. • Una variabile globale è dichiarata quando una variabile viene assegnato senza utilizzare la parola chiave var. • E 'buona pratica per dichiarare le variabili in campo livello globale utilizzando la parola chiave var. • locali e variabili globali con lo stesso nome non sovrascrivere l'altra. Un nasconde dichiarati localmente variabile a livello globale dichiarata variabile con lo stesso nome. • Quando una variabile non è dichiarato, utilizzando typeof sui risultati variabile indefinita. • Puoi rimuovere le variabili globali tramite l'operatore delete. • Quando si utilizzano le funzioni ricorsive, si dovrebbe utilizzare localmente variabili dichiarate. • ricorsione comporta in genere un inizializzazione e di esecuzione. Utilizzando JavaScript, l'inizializzazione e l'esecuzione può essere avvolto in una singola funzione. • inizializzazione confezionamento e l'esecuzione in una singola funzione utilizza le aspettative, dove la disponibilità di variabili è sottoposto a test per determinare un contesto di chiamata. • E 'possibile utilizzare eval dinamicamente dichiarare le variabili locali o globali. • Utilizzare eval fa sì che il processore JavaScript per non eseguire un look-ahead al momento di individuare le variabili locali. Così, per dichiarare una variabile locale, la parola chiave var deve essere utilizzato prima di assegnare una variabile. • Utilizzando l'istruzione eval, un programma potrebbe determinare in modo dinamico o meno di una variabile deve essere dichiarata in ambito locale o la portata globale. un articolo presentato da Sonja Lande Disclaimer:Il nostro sito non è responsabile per il contenuto di questo articolo. Webarticles è una risorsa gratuita di informazioni. Importante: Questo articolo "Capire il comportamento delle variabili quando attuazione ricorsione" è stato tradotto da un software automatico. Ci dispiace per eventuali errori di ortografia che possono essersi verificati. Grazie per la vostra comprensione.
|
|||||
| Online: 327 users browsing the articles directory |
|
|