Cómo detectar si un elemento se desborda (¿fuera de los límites?) usando javascript (no jquery)
Primero, veamos un ejemplo (por supuesto, puedes usar métodos más simples para lograrlo, aquí solo discutiremos la recursividad):
Ver código fuente
01 función esEven (num) {
02 if (num === 0) {
03 return true; p>05
06 if (num === 1) {
07 return falso
08 }
09
06 p>
10 Return isEven(Math.abs(num) - 2
11 }
12
13 //Resultado de salida: verdadero
14 console.log(isEven(10));
15
16 //Resultado de salida: falso
17 console. log(isEven(9));
18
19 // Resultado de salida: falselog(isEven(9));
Cuando cambiamos los parámetros Cuando 10000, ejecutar el siguiente ejemplo provocará un desbordamiento de pila:
01 function isEven (num) {
02 if (num === 0) {
03 devuelve verdadero;
04 }
05
06 if (num === 1) {
07 devuelve falso <; /p>
08 }
09
10 Return isEven(Math.abs(num) - 2
11 }
);12
13 // Diferentes motores de JavaScript pueden informar errores de manera diferente
14 //Salida: RangeError no detectado: se excedió el tamaño máximo de pila de llamadas
15 consola .log(isEven(10000));
La razón de esta situación es que se asigna un cierto tamaño de espacio de pila (1 M en Windows) cada vez que se ejecuta el código. cierta información (como parámetros, variables locales, valores de retorno, etc.) se almacenará en la pila. Incluso si esta información es pequeña, ocupará una cierta cantidad de espacio. Si se acumulan miles de esos espacios, naturalmente. Se excederá el espacio de la pila.
Entonces, ¿cómo solucionar este tipo de problema? Puedes comprobar 5 1 r g b
Usando cierres:
01 function isEven (num) {
02 if (num === 0) {
01 p>
03 devuelve verdadero
04 }
05
06 if (num === 1) { p>
07 retorno falso
08 }
09
10 retorno función() {
11 retorno esEven( Math.abs(num) - 2);
12 }
12 }
13 }
14 //Salida: verdadero
15 console.log(isEven(4)()());
En este caso, cada llamada devolverá una función anónima, y los parámetros y variables locales relacionados con la La ejecución de la función anónima se liberará sin aumentar el tamaño de la pila.
Optimizar la llamada:
El ejemplo anterior es un poco problemático al llamar, por lo que la optimización es la siguiente:
01 función esEven (num) {
02 if (num === 0) {
03 devuelve verdadero
04 }
05
06 if (num === 1) {
07 devolver falso
08 }
09
10 devolver función( ) {
11 return isEven(Math.abs(num) - 2
12 }
12./v_show/id_XMTMzMjk4NDUxMg=); =.html?f =26081534
13 }
14
15 función trampolín (func, arg) {
16 valor var = func(arg)
17
18 while(typeof valor === "función") {
19 valor = valor(); p>
20 }
21
22 Valor de retorno
23 }
24 //Resultado de salida: verdadero
25 console.log( trampoline(isEven, 10000));
26
27 //Resultado de salida: falso
28 console. .log( trampoline(isEven, 10001));
Ahora podemos resolver el problema de desbordamiento de la pila, pero no creemos que sea bueno llamar a tarmpoline(isEven, 1000) cada vez. enlazar a enlazar:/ v_show/id_
04 * @param {[tipo]} num [descripción]
05 * @return {Booleano}
03 * [isEvenInner recursivo]
04 * @param {[tipo]} num [descripción]
05 * @return {Boolean}[descripción]
06 */
07 función esEvenInner (n) {
08 if (n === 0) {
09 return true; >10 }
11
12 if (n === 1) {
13 return falso
14 } p>
15
15 p>
16 función de retorno() {
17 retorno esEvenInner(Matemáticas
.abs(n) - 2);
18 }
18 }
19 }
20 /**
21 * [Iteración del trampolín]
22 * @param {[tipo]} func [descripción]
23 * @param {[tipo]} arg [descripción]
24 * @return {[tipo]} [descripción]
37.
38 //Salida: verdadero
39 console.log (isEven(10000));
40
41 //Salida : false
42 console.log(isEven(10001));
Aunque el ejemplo anterior logra la función que queremos, la función de trampolín todavía tiene algunas limitaciones
1. Supongamos que solo pasa un parámetro a la función recursiva
value = func(arg); cambie a value = func.apply(func, arg);
2. Supongamos que el valor de retorno final no es una función
Para una implementación más sólida, consulte el código fuente en subrayado-contrib.
Gracias por leer este artículo. Espero que critique y corrija las inexactitudes del artículo. Este artículo se ha sincronizado con mi blog personal. Si tiene alguna buena sugerencia, deje un mensaje. !