Entender el comportamiento de las variables Al aplicar recursividadEntender el comportamiento de las variables cuando La aplicación de recursión Problema que desea aplicar la recursividad en JavaScript, y también desea entender cómo se comportan las variables en esas circunstancias. Teoría En JavaScript, no es necesario declarar el tipo de variable, o incluso declarar la variable. Por ejemplo, el siguiente código funciona perfectamente: if (contador == 1) ( tampón = "Contador es 1";) document.getElementById ( "resultado"). InnerHTML = tampón; La variable de amortiguamiento no fue declarado ante el bloque, si en el código anterior. La última línea del código utiliza la variable de amortiguación para asignar la propiedad innerHTML. Este tipo de declaración es problemática porque búfer podría ser indefinido. JavaScript no menciona esto como un error, y innerHTML se le asignará el valor indefinido. Este ejemplo muestra que las variables en JavaScript puede comportarse de forma que un programador con Java o C # de fondo no puede ser acostumbrado. El enfoque de esta receta está en averiguar cómo se comporta una variable en diferentes contextos. Un ejemplo es el contexto de la aplicación de la recursividad en JavaScript. Solución de dos funciones de ejemplo que aplicar la recursividad en JavaScript seguir. Fuente: / web / ROOT / ajaxrecipes / JavaScript / variablebehavior.html función RecursionGlobal (contador) (info ( "RecursionGlobal () localCounter", typeof (localCounter)); localCounter = contador; info ( "RecursionGlobal () localCounter", localCounter), si (localCounter <3) (RecursionGlobal (localCounter + 1);)) function RecursionLocal (contador) (info ( "RecursionLocal () localCounter", typeof (localCounter)); var = localCounter mostrador; info ( "RecursionLocal () localCounter", localCounter), si (localCounter <3) (RecursionLocal (localCounter + 1);)) El ejemplo muestra dos métodos: RecursionGlobal y RecursionLocal. Entre los dos métodos hay una sola diferencia, como se muestra en el código en negrita: la palabra clave var JavaScript. La palabra clave var solo es la variación de cómo se almacena la variable localCounter. El comportamiento de ambos métodos es idéntico cuando se ejecuta y genera el mismo resultado. Usted puede pensar a primera vista que la palabra clave var no sirve a ningún propósito. Pero la palabra clave var sirve a un propósito, que se ilustra mediante la ejecución del siguiente programa: Info: recursion_global *** *** Started Info: RecursionGlobal () localCounter Información indefinido: RecursionGlobal () localCounter 1 Info: RecursionGlobal () localCounter número Info: RecursionGlobal () localCounter 2 Info: RecursionGlobal () localCounter número Info: RecursionGlobal (localCounter 3) Info: recursion_local *** *** Started Info: RecursionLocal () localCounter Información indefinido: RecursionLocal () localCounter 1 Info: RecursionLocal () localCounter Información indefinido: RecursionLocal () localCounter 2 Info: RecursionLocal () localCounter Información indefinido: RecursionLocal (3) localCounter
Observe que cuando la función RecursionGlobal ejecuta, el tipo de la localCounter para la primera convocatoria no está definido, y, posteriormente, es el número. En cambio, cuando la función RecurisonLocal se llama, el tipo de localCounter no está definido para cada llamada. Esto significa que var sirve al propósito de declarar una variable que es local en el ámbito de aplicación de la que se declara. Si la variable no está asociado con una palabra clave var, a continuación, la variable se declara en el ámbito global. En el caso de la creación de un bucle de la recursividad, tendrá que utilizar la palabra clave var en todos los casos, de lo contrario, podría haber corrupción de datos. El siguiente ejemplo ilustra la forma de cambiar el contenido de una pila de uso de la recursividad. Cuando se utiliza la recursividad, a veces tendrán que declarar los parámetros de función que no sirven a ningún propósito que no sea como valores de referencia. Fuente: / web / ROOT / ajaxrecipes / JavaScript / variablebehavior.html función RecursiveStackOldWay (arrayToProcess, processedArray) (info ( "RecursiveStackOldWay", "---> Inicio "); info (" RecursiveStackOldWay "," profundidad recursivas = "+ (processedArray. longitud + 1)); processedArray.push (arrayToProcess.pop ()); si (arrayToProcess.length> 0) (RecursiveStackOldWay (arrayToProcess, processedArray);) info ( "RecursiveStackOldWay", "---> End ");) arrayToProcess var = new Array (); arrayToProcess.push ( "valor1"); arrayToProcess.push ( "valor2"); processedArray var = new Array () RecursiveOldWayStack (arrayToProcess, processedArray); Aquí, la función RecursiveStackOldWay tiene dos parámetros: arrayToProcess y processedArray. El primer parámetro, arrayToProcess, es la matriz que se invierta. El segundo parámetro, processedArray, es el destino de pila. El destino de pila necesita ser arrastrado como un parámetro para cada recursión, para que la función puede poner la pila en algún lugar. La persona es responsable de crear instancias de la pila de destino y pasar a la función recursiva. A menudo, sin embargo, al crear funciones recursivas , usted tendrá que llamar a la función con ciertos parámetros que se definen en la parte superior del primer nivel de convocatoria. Estos parámetros no tienen nada que ver con la llamada inicial, sin embargo, la parte superior de primer nivel necesita llamar a declarar a (processedArray). En pocas palabras, el problema es que cuando se llama a una función recursiva, se necesita inicializar un conjunto de variables que luego son utilizados por la recursividad. En el ejemplo, la inicialización es una responsabilidad de la persona que llama. Las obras de solución, pero está lejos de ser óptima, ya que el desarrollador tiene que entender cómo se comportan ciertos parámetros de la función, a pesar de que no puedan ser utilizados por la persona que llama. Otra solución es crear una función contenedora a la recursividad que inicializa los parámetros y luego llama a la recursividad. La función contenedora funcionará, pero ahora el programador tiene que mantener la función de la recursividad y la función contenedora. JavaScript ofrece una tercera solución: que la función de la recursividad inicializarse. La pregunta es, ¿cómo la función de recursividad saber que se pidió por primera vez? En un lenguaje de programación tradicionales como Java o C #, un parámetro booleano se define y se establece en true para indicar la primera convocatoria, y false para indicar cualquier llamada posterior. La solución JavaScript no requiere una bandera o un indicador, porque los parámetros sí son indicadores. Por ejemplo, imagine si la función de implementación RecursiveOldWayStack se queda como está y el código que llama RecursiveOldWayStack similar al siguiente: arrayToProcess var = new Array (); arrayToProcess.push ( "valor1"); arrayToProcess.push ( "valor2"); processedArray var = RecursiveOldWayStack (arrayToProcess); En la ejecución vez no, la persona que llama es responsable de crear instancias de la pila de destino. Esa responsabilidad se ha delegado la función de RecursiveOldWayStack. Sin embargo, surge un problema, porque RecursiveOldWayStack necesita para inicializar y comenzar la recursividad. La solución utilizada por JavaScript es determinar si el segundo parámetro se define, como se ilustra en la función modificado a raíz de llamada RecursiveStack. Fuente: / web / ROOT / ajaxrecipes / JavaScript / variablebehavior.html función RecursiveStack (arrayToProcess, processedArray) (info ( "RecursiveStack", "---> Inicio "); if (typeof (processedArray) == "undefined") ( info ( "RecursiveStack", "Inicial"); processedArray = new Array (); RecursiveStack (arrayToProcess, processedArray); info ( "RecursiveStack", "---> End "); processedArray retorno; )else (info ( "RecursiveStack", "profundidad recursivas =" + (processedArray.length + 1)); processedArray.push (arrayToProcess.pop ()); si (arrayToProcess.length> 0) (RecursiveStack (arrayToProcess, processedArray); ) info ( "RecursiveStack", "---> End "); return;)) En la ejecución vez, la función RecursiveStack implementa una expectativa. La expectativa es que si la función se llama con un parámetro único, entonces es una persona que llama hacer la primera llamada de la recursividad, de lo contrario, una recurrencia que está sucediendo. La expectativa de saber si una primera convocatoria que está sucediendo es determinado por el código en negrita. Si el segundo parámetro, processedArray, no se define, entonces la función recursiva inicializa a sí mismo y empieza la recursividad. Si no se define el segundo parámetro, entonces se asume una recursión que está pasando, y la función de procesar los datos como tales. Antes de continuar, podría haber capturado el hecho de que RecursiveStack tiene dos parámetros, pero se está llamando a uno. Antes he hablado de las expectativas y que la persona que llama tiene que pasar dos parámetros. Este ejemplo no se que decir que la persona que llama no tiene que pasar dos parámetros, más bien, el ejemplo dice que si la persona que llama no pasa dos parámetros, la función tiene la capacidad para compensar. La misma función puede ser utilizado para la inicialización y la recursividad sobre la base de una expectativa. Sin embargo, si la persona que llama se define el segundo parámetro, eso significa que la persona que llama ha asumido la responsabilidad de aplicar la inicialización. Con una llamada definida de la inicialización, RecursiveStack no llevará a cabo una inicialización y saltar directamente a la funcionalidad de la recursividad. La ventaja de esta solución es que usted tiene una función polivalente, sin tener que definir explícitamente una función contenedora. Usted puede estar pensando: "Por supuesto que esto es posible utilizando un lenguaje como Java o C # utilizando funciones sobrecargados." Sí, es posible utilizar funciones sobrecargadas, pero como se mencionó anteriormente, una función de sobrecarga es una función contenedora que pide la aplicación efectiva , es decir, dos funciones deben ser por escrito y mantenido. En JavaScript, todo puede ser envuelto en un equipo autónomo de la función. Ahora que se ha aplicado la recursividad y saber la diferencia entre una variable de ámbito local y una variable de ámbito global, la siguiente pregunta es, ¿qué ocurre si hay dos variables con el mismo nombre? Imagine la definición de una variable en un ámbito local que existe en el ámbito global lo que sucede al nivel mundial y local con ámbito de las declaraciones de variables? El código siguiente muestra cómo una variable se define a nivel mundial en una función y luego se hace referencia en otra función. Fuente: / web / ROOT / ajaxrecipes / JavaScript / variablebehavior.html función GlobalScope () (info ( "GlobalScope () scopedVariable", typeof (scopedVariable)); scopedVariable = "Globalscope"; info ( "GlobalScope (scopedVariable)", "scopedVariable =" + + scopedVariable ➥ "type =" + typeof (scopedVariable));) function TestScope () (info ( "OtherScope (scopedVariable)", "scopedVariable = "+ scopedVariable + "Type =" + ➥ typeof (scopedVariable));) scopedVariable se define en GlobalScope y se hace referencia en TestScope. Dado que no hay var basado en la declaración de scopedVariable en GlobalScope, scopedVariable se pone en el ámbito global. Correr TestScope después GlobalScope resultará en scopedVariable se define a nivel mundial, como se muestra en la salida generada siguientes: Info: GlobalScope () scopedVariable Información indefinido: GlobalToLocalScope (scopedVariable) scopedVariable type = globalscope = Información cadena: TestScope (scopedVariable) scopedVariable type = globalscope = cadena En la salida generada, GlobalScope se llama, y al comienzo de la implementación de la función, scopedVariable no está definido. Luego scopedVariable se le asigna un buffer, y el resultado generado scopedVariable indica que no es indefinido y hace referencia a una cadena. Llamadas TestScope ilustra que scopedVariable es global y se le asigna un búfer. Consideremos ahora el mismo ejemplo, con excepción de una variable de ámbito global es declarado de nuevo como un la variable local mediante la palabra clave var. Fuente: / web / ROOT / ajaxrecipes / JavaScript / variablebehavior.html función AlwaysLocalScope () (info ( "GlobalToLocalScope () scopedVariable", typeof (scopedVariable)); scopedVariable = "AlwaysLocalScope"; info ( "GlobalToLocalScope () scopedVariable", "scopedVariable = "+ + scopedVariable ➥" type = "+ typeof (scopedVariable)); scopedVariable var;) En la implementación de la función, es la primera scopedVariable le asigna un búfer que no utiliza la palabra clave var. Por lo tanto, scopedVariable se declara en el nivel de ámbito mundial. O al menos eso es lo que quieren hacer creer. Lo que sucede es que la variable se declara en el nivel local, porque la última instrucción de la función (en negrita) declara la variable scopedVariable a ser locales. Puede parecer extraño que se declara una variable a ser local, si en algún lugar de la función de la var palabra clave se utiliza. Se hace aún más extraño, en que si la palabra clave var se utiliza en un bloque de decisión que nunca se ejecuta, la variable sigue siendo declarado local. Para ilustrar, en primer lugar la función AlwaysLocal se llama y luego TestScope, que genera el siguiente resultado: Info: AlwaysLocalScope () scopedVariable Información indefinido: AlwaysLocalScope (scopedVariable) scopedVariable = = AlwaysLocalScope Avisar tipo de cadena: Error general (scopedVariable no está definido) Cuando se llama a la función AlwaysLocalScope, scopedVariable será indefinido, lo que significa que existe en el ámbito de aplicación, ni globales ni locales. Luego, cuando se asigna a la variable, la salida generada tendrá un valor y tipo. Cuando se llama a la función TestScope, se produce una excepción, porque scopedVariable no está definido. Ahora ya sabes, cuando se declara una variable en el ámbito global y en ámbito local. La última prueba es ver lo que ocurre cuando una variable se declara en tanto globales como locales ámbito de aplicación. La prueba consiste en llamar a las funciones en la secuencia: GlobalScope, TestScope, AlwaysLocalScope y, a continuación TestScope. Llamar a esta secuencia genera el siguiente resultado: Info: GlobalScope () scopedVariable Información indefinido: GlobalScope (scopedVariable) scopedVariable type = globalscope = Información cadena: TestScope (scopedVariable) scopedVariable type = globalscope = Información cadena: AlwaysLocalScope () scopedVariable Información indefinido: AlwaysLocalScope (scopedVariable) scopedVariable = AlwaysLocalScope Tipo = String Info: TestScope (scopedVariable) scopedVariable type = globalscope = cadena En la salida generada, scopedVariable es declarado y asignado en GlobalScope. La función TestScope verifica que scopedVariable existe. Luego, cuando se llama a AlwaysLocalScope, var declara que toda referencia a scopedVariable dentro de la función es una referencia variable local. Por lo tanto, si hay una variable definida por el mundo con el mismo nombre, no es accesible en el ámbito de la función. Usted tiene dos maneras de hacer referencia a una variable global: la referencia a través de la ventana de la propiedad o la creación de una función que es ajena a la función de ejecución (es decir, no es una función en línea) y la asignación de la variable de ámbito global. Cuando una variable no está asignada, la typeof devuelve la función definida. Una vez que se asigna una variable, typeof volverá otro valor. Si una variable se define en el contexto de una función, entonces cada uno y cada vez que la función es llamada, la variable antes de ser asignado será indefinido. A nivel mundial, una variable puede ser quitado mediante el operador delete, como sigue: eliminar scopedVariable; Normalmente, el operador delete se usa para restablecer la propiedad de un objeto. Al borrar se usa con un identificador, una referencia de variable global es eliminado. No se puede quitar una referencia a una función mediante eliminar. Vamos a probar otra variante del ámbito de aplicación utilizando el código dinámico. En JavaScript, utilizando la función eval se ejecutará un buffer de JavaScript, que las pruebas cuando una variable se tendrán en cuenta el alcance mundial y, cuando se considerará ámbito local. La función de AlwaysLocalScope tanto, será modificado. Para la primera variación, AlwaysLocalScope tendrá una asignación dinámica: función AlwaysLocalScope () (info ( "AlwaysLocalScope () scopedVariable", typeof (scopedVariable)); eval ( "scopedVariable = 'AlwaysLocalScope'");info ( "AlwaysLocalScope (scopedVariable)", "scopedVariable =" + + scopedVariable ➥ "type =" + typeof (scopedVariable)); scopedVariable var;) El código modificado se muestra en negrita, y la asignación de scopedVariable se ejecuta. Uso de eval de esta manera no tiene ningún efecto, y la ejecución dinámica del código es el mismo que si el código no ha sido modificado. La ventaja de eval es que se puede asignar una porción de código a un búfer de texto, y luego ejecutar ese buffer. El ámbito de aplicación de scopedVariable no ha cambiado, porque la palabra clave var, todavía existe en la declaración de función. Cuando se analiza la declaración por el procesador de JavaScript dará lugar a una declaración de variable local. Una forma de cambiar el comportamiento declaración local es integrar la declaración de la variable en una instrucción eval, como se muestra en la modificación de código siguiente: función AlwaysLocalScope () (info ( "AlwaysLocalScope () scopedVariable", typeof (scopedVariable)); eval ( "scopedVariable = 'AlwaysLocalScope'");info ( "AlwaysLocalScope (scopedVariable)", "scopedVariable =" + + scopedVariable ➥ "type =" + typeof (scopedVariable)); eval ( "scopedVariable var;");) El código modificado con respecto al código AlwaysLocalScope original está en negrita. Esta vez, tanto la cesión como la declaración de scopedVariable son dinámicos, lo que significa que cuando se asignan scopedVariable será tratada como una variable global. Esto es porque cuando se ejecuta la instrucción eval en primer lugar, no hay declaración de scopedVariable, y el tiempo de ejecución de JavaScript almacenará scopedVariable en el espacio global. Para cambiar el comportamiento y declarar scopedVariable como una variable local, AlwaysLocalScope necesita ser modificado una vez más , como sigue: función AlwaysLocalScope () (info ( "AlwaysLocalScope () scopedVariable", typeof (scopedVariable)); eval ( "scopedVariable var;"); eval ( "scopedVariable = 'AlwaysLocalScope'");info ( "AlwaysLocalScope (scopedVariable)", "scopedVariable =" + + scopedVariable ➥ "type =" + typeof (scopedVariable));) En la última modificación, la eval primero es la declaración de scopedVariable utilizando la palabra clave var. Los primeros resultados ponen eval en la declaración de scopedVariable como una variable local. La llamada eval segundo asigna un valor a scopedVariable, que es como una variable de ámbito local. Cuando la declaración de variables en el contexto de las funciones o en el ámbito global, mantenga en mente los siguientes puntos: • Hay dos ámbitos a una variable local a una función y mundial. • Una variable local se declara usando la palabra clave var, con la excepción del uso de var en un contexto global. El uso de var no necesita estar en el inicio de una función. • Una variable global se declara cuando se le asigna una variable sin utilizar la palabra clave var. • Es una buena práctica para declarar variables en el ámbito de aplicación a nivel mundial utilizando la palabra clave var. • Locales y las variables globales con el mismo nombre no se eliminan mutuamente. Una variable local oculta declarado a nivel mundial variable declarada con el mismo nombre. • Cuando una variable no se declara, utilizando typeof en los resultados variables en indefinido. • Usted puede unset variables globales usando el operador delete. • Cuando utilice las funciones recursivas, debe usar variables declaradas local. • Recursión normalmente implica una inicialización y de una ejecución. Uso de JavaScript, la inicialización y ejecución pueden ser envueltos en una sola función. • Inicialización de ajuste y la ejecución en una sola función utiliza las expectativas, donde la disponibilidad de las variables es la prueba para determinar el contexto de la llamada. • Es posible utilizar eval dinámicamente declarar variables locales o globales. • Uso de eval provoca que el procesador de JavaScript para no realizar un anticipado la hora de identificar las variables locales. Por lo tanto, para declarar una variable local, la palabra clave var debe ser utilizado antes de asignar una variable. • Uso de la sentencia eval, un programa de dinámica podría determinar si procede o no una variable que debe ser declarada en el ámbito local o el ámbito mundial. un artículo presentado por Sonja Lande Descargo de responsabilidad:Nuestro sitio web no es responsable por el contenido de este artículo. Webarticles es un recurso de información gratuito. Importante: Este artículo "Entender el comportamiento de las variables Al aplicar recursividad" fue traducida por un software automático. Sentimos pena por los errores de ortografía que pueda haber ocurrido. Gracias por su comprensión.
|
|||||
| Online: 368 users browsing the articles directory |
|
|