2010-01-08 12 views
10

que tienen un poco de código que se parece a esto: las reclamaciones de perfil del¿Cuáles son las alternativas para evaluar en JavaScript?

function StrippedExample(i1, i2, i3, i4, i5, i6, i7, i8) { 
    this.i = []; 
    for (var i=1,j=0 ;i<9;i++) { 
     var k = eval("i"+i); 
     if (k > 0) { 
      this.i[j++] = k; 
     } 
    } 
} 

FireBug segunda función que es más larga eval(), teniendo un máximo de casi el 6% del tiempo de ejecución.

Everyone says eval is EVIL (como en mal) y lento (como he encontrado), pero realmente no puedo hacer nada más: el servidor simplemente extrae los datos de la base de datos y los empuja hacia el navegador.

¿Qué alternativas tengo? Podría hacer lo mismo que hago aquí en el servidor, pero eso simplemente desplaza la carga más arriba en la cadena. No puedo cambiar el diseño de la base de datos ya que todo se engancha en esas 8 variables y es una tarea enorme.

+3

Esperemos que esto ayude a mostrar a las personas que nunca tiene que usar 'eval'. – ChaosPandion

Respuesta

13
function StrippedExample(i1, i2, i3, i4, i5, i6, i7, i8) { 
    var args = [i1, i2, i3, i4, i5, i6, i7, i8]; // put values in an array 
    this.i = []; 
    for (var i=0,j=0 ;i<8;i++) { // now i goes from 0-7 also 
     var k = args[i]; // get values out 
     if (k > 0) { 
      this.i[j++] = k; 
     } 
    } 
} 

El código anterior se puede simplificar aún más, acabo de hacer el cambio mínimo para deshacerse de eval. Puede deshacerse de j, por ejemplo:

function StrippedExample(i1, i2, i3, i4, i5, i6, i7, i8) { 
    var args = [i1, i2, i3, i4, i5, i6, i7, i8]; 
    this.i = []; 
    for (var i = 0; i < args.length; i++) { 
     var k = args[i]; 
     if (k > 0) { this.i.push(k); } 
    } 
} 

es equivalente. O, para usar el objeto arguments incorporado (para evitar tener su lista de parámetros en dos lugares):

function StrippedExample(i1, i2, i3, i4, i5, i6, i7, i8) { 
    this.i = []; 
    for (var i = 1; i < arguments.length; i++) { 
     var k = arguments[i]; 
     if (k > 0) { this.i.push(k); } 
    } 
} 

Incluso si no estaban filtrando la lista, usted no quiere hacer algo así porque this.i = argumentsarguments no es una matriz real; tiene una propiedad callee que no necesita y le faltan algunos métodos de matriz que podría necesitar en i. Como otros han señalado, si se quiere convertir rápidamente el objeto arguments en una matriz, puede hacerlo con esta expresión:

Array.prototype.slice.call(arguments) 

Usted podría utilizar que en lugar de los var args = [i1, i2 ... líneas anteriores.

+1

Este código es actualmente incorrecto, ya que usa 1 indexación mientras que la matriz está indexada en 0. También es definitivamente más complicado de lo que necesita ser, ya que podría simplemente reemplazar 'args' con la matriz incorporada' arguments', y no definirlo usted mismo. –

+0

Gracias por captar eso, Brian. Creo que lo arreglé – benzado

+1

Ahora te has perdido la parte 'if (k> 0)' del original. –

5
  1. Llame a la función con un argumento - una matriz
  2. Uso del objeto arguments
1

Este código se debe hacer para utilizar la matriz arguments que cada función Javascript tiene acceso.

No es que eval es mal (está en Lisp, así que debe ser bueno ) es simplemente un signo de un hack - se necesita algo para trabajar y que lo obligó. Me grita "El autor se dio por vencido en el buen diseño de programación y acaba de encontrar algo que funcionó".

+0

No soy sincero con todos los pormenores de Javascript. Puedo hackear para hacer las cosas, pero como se demuestra aquí, no siempre es la mejor manera. –

0

Dado que hay una cantidad fija de variables, puede construir una matriz de ellas manualmente y recorrerlas.Pero si usted tiene una cantidad variable de argumentos, una forma de obtener las variables pasan a la función como una matriz es:

var args = Array.prototype.slice.call(arguments.callee.caller.arguments); 

y su función se vería así:

function StrippedExample() { 
    var args = Array.prototype.slice.call(arguments.callee.caller.arguments); 
    for(var i in args) { 
     if (args[i] > 0) { 
      this.i[j++] = args[i]; 
     } 
    } 
} 
+0

necesita editar la k con args [i] e inicializar la j –

+2

No debe usar 'for..in' para iterar las matrices. Un simple 'for' loop es mejor. – JPot

7

Eres simplemente hacer una matriz a partir de los argumentos de su función 8, eliminando los que son menores o iguales a cero.

El código siguiente es equivalente, y funcionará para cualquier número arbitrario de argumentos:

function StrippedExample() { 
    var args = []; 

    for (var i = 0; i < arguments.length; i++) { 
    if (arguments[i] > 0) { 
     args.push(arguments[i]); 
    } 
    } 
    //... 
} 
+0

No olvide la parte 'if (k> 0)'. – JPot

+0

@JPot, gracias, agregó la condición ... – CMS

4

Una alternativa a pasar una matriz a su función, en lugar de argumentos individuales:

StrippedExample([3, 1, 4, 1, 5, 9, 2, 6]) 

Entonces su código sería:

function StrippedExample(inArray) { 
    this.i = []; 
    for (var i=0,j=0 ;i<inArray.length;i++) { 
     var k = inArray[i]; 
     if (k > 0) { 
      this.i[j++] = k; 
     } 
    } 
} 

Si realmente necesita pasar por separado argumentos, puede acceder a ellos usando su matriz arguments, que es un objeto que actúa como una matriz (aunque en realidad no lo es; no todos los métodos Array funcionan en él) que expone todos los argumentos que se han pasado a su función; que ni siquiera necesitan ser declaradas en este caso, pero es buena forma de incluir un comentario que indica qué tipo de argumentos que usted está esperando para los usuarios de su código:

function StrippedExample(/*i1, i2, i3, i4, i5, i6, i7, i8*/) { 
    this.i = []; 
    for (var i=0,j=0 ;i<arguments.length;i++) { 
     var k = arguments[i]; 
     if (k > 0) { 
      this.i[j++] = k; 
     } 
    } 
} 

Si tiene la garantía de que sólo tienen 8 elementos, entonces podría usar 8 en lugar de inArray.length o arguments.length; Decidí usar la versión más general en mis ejemplos en caso de que fuera útil para usted.

+0

me ganó por 10 segundos ... –

1
function StrippedExample() { 

    this.i = []; 
    for (var i=1,j=0 ;i<arguments.length;i++) { 
     var k = arguments[i]; 
     if (k > 0) { 
      this.i[j++] = k; 
     } 
    } 
} 
0

Eval alternativa:

exp = '1 + 1' 
x = Function('return ' + exp)() 
console.log(x) 

Es esto lo que está buscando?

Cuestiones relacionadas