Pregunta

¿Hay algún impacto en el rendimiento para la escritura de una función tal que las declaraciones var locales se reemplazan con argumentos? Ejemplo:

function howManyMatch(arr, pattern, /*ignored:*/ i, l, total) {
  l = arr.length;
  total = 0;
  for (i = 0, i < l; i++) {
    if (pattern.test(arr[i]))
      total++;
  return total;
}

Algunas ventajas:

  • pequeño tamaño miniaturizada: no hay declaraciones var;
  • programador menos tiempo dedicado a tratar de utilizar el menor número posible de vars
  • todos los VARs locales definidas en un solo lugar

... y desventajas:

  • arguments puede ser alterado de forma inesperada. Véase más abajo
  • menos clara en el cuerpo que VARs son locales
  • confuso para ver los argumentos que no hacen nada
  • si alguien, sin saberlo, los elimina, el código se escribe en variables globales

Todavía podría ser una manera fácil para un Minifier para exprimir automáticamente más bits.

Actualización: una gran desventaja no mencionados hasta ahora: Si una función es llamada con parámetros N, los primeros n elementos de arguments serán encuadernados a los primeros N identificadores en la lista de argumentos (véase el última bala en 10.1.8 ). Considere lo siguiente:

function processStuff(/*ignored:*/i, j, k) {
    // use i/j/k to loop
    // do stuff with the arguments pseudo-array
}

En el ejemplo anterior, si se llama a processStuff(stuff1, stuff2), el establecimiento de i y j se sobrescribir arguments[0] y arguments[1] respectivamente.

¿Fue útil?

Solución

No lo haría por muchas de las razones que ya conoce, personalmente no me gusta el hecho de mezclar el significado semántico de argumentos frente a las variables, aunque a nivel de aplicación, cuando se ejecuta la función, que son propiedades sólo del objeto variable actual, tienen significado diferente de la OMI.

Ahora, respondiendo a la pregunta, No creo que haya ninguna repercusión en el rendimiento .

Déjame hablar un poco acerca de la proceso de creación de instancias de variables , que se lleva a cabo para la función de Código, justo antes de que se ejecute la función (comúnmente conocido como "elevación"), en un primer momento, todo el parámetros formales descrito para la función están obligados a la variable de objeto actual (el ámbito actual), y se inicializan con los valores pasados ??en la llamada de función o undefined si no suministrado.

Después de eso, todos los identificadores que pertenecen a todas las declaraciones var dentro de la función se declaran en el ámbito actual, e inicializado con undefined (nota que las asignaciones se hacen después de esto, el cuerpo de la función es en realidad no se está ejecutando aún) .

El tercer paso se FunctionDeclarations, todos los identificadores de declaraciones de función están unidos al ámbito local, si un identificador se declaró anteriormente, se sustituye su valor, por ejemplo:

(function (a) {
  return typeof a; // "function", not "string"

  function a () {}

})('foo');  // <-- passing a string

Yo recomendaría su lugar simplemente usar una sola instrucción var, en la parte superior de la función:

function howManyMatch(arr, pattern) {
  var l = arr.length,
      total = 0, i;
  for (i = 0, i < l; i++) {
    if pattern.test(arr[i]) && total++;
  return total;
}

Esto no solo organizar el código, que ayudaría a evitar resultados no deseados debido al alcance-función sólo de JavaScript y la naturaleza "elevación" de var, algunas herramientas como JSLint fomentar esto también.

Otros consejos

No, no me hagas esto. Es confuso e innecesario. Y me encuentro con su lista de "ventajas" a ser muy engañoso -. Cada plato hay muy delgada en cuanto al beneficio real obtenido

Si tiene que, sólo tiene que utilizar el operador de coma y declarar todas las variables en una sola instrucción a la derecha en la cabeza de la función (que están izadas a este lugar de todos modos.

function howManyMatch(arr, pattern) {
  var i, l, total;
  // rest
}

O puede declarar / definir todo en una vez paso demasiado

function howManyMatch(arr, pattern) {
  var l = arr.length, total = 0, i = 0;
  // rest
}

Creo que la legibilidad y facilidad de mantenimiento y tamaño de archivo outweight microoptimizations aquí. Es más más fácil de leer código que tiene la palabra clave var. Además de eso, una declaración por var alcance debería ser suficiente (que es donde ellos JavaScript iza, de todos modos). Todo variables locales están disponibles todas partes en el ámbito local (independientemente del orden en que han sido declarados). Así que todas las variables locales deben ser declarados en la misma posición (al comienzo del ámbito local) a la mejor legibilidad. Estos cuatro bytes para la declaración var no son realmente vale la introducción de posibles errores al permitir al usuario establecer los valores iniciales de las variables locales llamando a esa función con parámetros adicionales. Se rompe la encapsulación (que puede obtener este derecho, sino que va a terminar con más bytes que guardó omitiendo var). Además de eso, es realmente confuso para cualquier persona que está tratando de leer su código.

Las mismas ventajas que facilite, se puede lograr sólo la eliminación de la palabra clave var:

function howManyMatch(arr, pattern) {
  l = arr.length;
  total = 0;
  for (i = 0; i < l; i++) {
    if pattern.test(arr[i]) && total++;
  return total;
}

No hay necesidad de escribir explícitamente la palabra clave var, como se va a definir todas las variables en este caso con un valor (l = arr.length, total = 0, i = 0).

Por cierto, el aviso que pueda no variables predefinir por definirlas como argumentos de la función. Esto no es posible, por ejemplo:

function howManyMatch(arr, pattern, i=0, l, total = 0){ ... }

Por lo tanto, no creo que la solución de código Minify es muy útil después de todo, ya que se mantienen las desventajas;)


Editar

Yo no pensaba en el hecho de que la definición de las variables sin la palabra clave var sería convertirlos en variables globales. Eso podría ser algo que usted no desea en absoluto ...

Pero cuando pienso en el problema de nuevo, no veo por qué desea para definir las variables de argumentos de la función. Todas las ventajas que usted da para ese método, son básicamente cierto para este ejemplo también:

function howManyMatch(arr, pattern) {
  var l = arr.length, total = 0, i=0;
  for (; i < l; i++) {
    if pattern.test(arr[i]) && total++;
  return total;
}

Y este ejemplo es aún más corto.

Chistian Johansen en "Test-Driven Desarrollo Javascript" (2011) afirma: "En general, el objeto argumentos sólo debe usarse cuando los parámetros formales no pueden resolver el problema en cuestión, porque el uso que viene con un precio de ejecución, de hecho. , simplemente hace referencia al objeto inducirá cierta sobrecarga, lo que indica que los navegadores optimizar funciones que no lo usan ".

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top