The linked video explains why closure can inflict some performance hits starting about 11:08.
Básicamente, él está diciendo que para cada función anidada, se agrega otro objeto a la cadena de ámbito y por lo tanto el acceso a las variables exterior del cierre se llevará más tiempo.
Para encontrar el valor asociado a una variable, el interprer Javascript sigue este proceso:
- buscar el objeto ámbito local
- si 1 no funcionó, buscar el objeto ámbito padre
- si 2 no funciona, búsqueda de objetos ámbito primario de los padres
- seguir buscando ámbitos principales hasta
- se busca el ámbito global
- y si aún no se encuentra, arroje un error variable indefinido.
En una función normal, para encontrar una variable, solo tiene que buscar en la parte superior de la cadena de ámbito. Un cierre, por otro lado, para encontrar variables padre tendrá que buscar en la cadena del alcance, a veces varios niveles de profundidad. Por ejemplo, si usted tenía algunos cierres de este tipo (tenga en cuenta que este es un ejemplo muy artificiosa):
function a (x) {
function b (y) {
return (function (z) {
return x + y + z;
})(y + y);
}
return b(x + 3);
}
De la función más interna, para evaluar la expresión x + y + z
, tiene que recorrer hasta tres niveles en el cadena de alcance para encontrar x, luego tiene que atravesar la cadena del alcance dos niveles para encontrar y, finalmente, una vez para encontrar z.En total, tuvo que buscar seis objetos en la cadena de alcance para devolver el resultado final.
Esto es inevitable en los cierres, porque cierres siempre tienen que acceder a las variables principales. Si no lo hicieran, no tendría sentido usar un cierre.
También tenga en cuenta que en Javascript, hay una sobrecarga significativa en la creación de funciones, especialmente cierres. Tomemos, por ejemplo, este bastante simple cierre:
function a(x) {
return function (y) {
return x + y;
}
}
Y usted lo llama varias veces diferentes, como este
var x = a(1);
var y = a(2);
var z = a(3);
alert(x(3)); // 4
alert(y(3)); // 5
alert(z(3)); // 6
Se dará cuenta de que la función de regresar de a
tiene que mantener lo que pasó como argumento en la función primaria incluso después de que ya se haya llamado a la función padre. Esto significa que el intérprete debe mantener en la memoria lo que pasó en cada función que ha llamado hasta ahora.
Solo recuerde: la optimización prematura es la raíz de todo mal. El video trata sobre hacer que JavaScript sea más eficiente, sin embargo, la mayoría de JavaScript nunca necesita ser optimizado. Si tiene una llamada a una función configurada de forma asincrónica después de que un usuario hace clic en un botón, el usuario nunca notará la diferencia entre una tasa de respuesta de 30 ms y una tasa de respuesta de 40 ms. – zzzzBov
Las respuestas aquí son todas buenas. Recuerde, sin embargo, que el video tiene un par de años, y puede no ser tan relevante como lo fue el t. –