2010-08-03 19 views
5

Recientemente, un compañero desarrollador me reprendió por usar "matemáticas de cuerda" en una aplicación que escribí. Soy bastante nuevo en todo el desarrollo, sin formación formal, y no he oído hablar de este tema. ¿Qué es?¿Qué es "matemática de cuerdas" y por qué es malo?

código en cuestión:

$('.submit-input').click(function() { 
    var valid = true; 
    $('input, select, radio').removeClass('error'); 
    $('.error-message').hide(); 

    $('.validate').each(function() { 
     if($(this).val() == $(this).attr('default')){ 
      valid = false; 
      $(this).addClass('error'); 
     } 
    }); 

    if(!$('select[name="contact"] option:selected').val() != ''){ 
     $('select[name="contact"]').addClass('error'); 
     valid = false; 
    } 

    if(!$('input[name="ampm"]:checked').length){ 
     $('input[name="ampm"]').addClass('error');   
     valid = false; 
    } 

    if(!valid){ 
     $('.error-message').css('display','block'); 
     return false; 
    } else { 

     var services_selected = 'Services Selected: '; 
     services_selected += $('.l3').text() + ', ' + $('.l4').text() + ', ' + $('.l5').text() + '; ' + $('.l6').text(); 
     var prices = 'Prices: '; 
     prices += $('.l7').text() + ', ' + $('.l8').text() + ', ' + $('.l9').text() + ', ' + $('.l10').text(); 
     var name = 'Name: '; 
     name += $('input[name="name"]').val(); 
     var phone = 'Phone: ' 
     phone += $('input[name="phone"]').val(); 
     var time = 'Preferred contact time: '; 
     time += $('select[name="contact"] option:selected').val() + $('input[name="ampm"]:checked').val(); 

     $.ajax({ 
      url: 'php/mailer.php', 
      data: 'services_selected=' + services_selected +'&prices=' + prices + '&name=' + name + '&phone=' + phone + '&time=' + time, 
      type: "POST", 
      success: function() { 
       $('#email_form_box .container').children().fadeOut(500, function() { 
        $('#email_form_box .container').html('<div style="margin:20px auto;text-align:center;width:200px;">yada yada yada<br /><span class="close">Close</span></div>'); 
       }); 
      } 
     }); 
    } 

}); 

Editar: La esencia me estoy aquí es que esto no es una expresión coloquial de desarrollo estándar, y probablemente debería hablar con el chico que me dio impertinencias en el primer lugar. Entonces haré eso. Gracias chicos. Volveré con una respuesta, o marcaré a quien ya sabía.

+4

Creo que solo tu amigo sabe acerca de ** "matemáticas de cuerda" ** cosa :) – Sarfraz

+6

Muéstranos el código al que se opuso. – tpdi

+4

Entonces, ¿por qué no le hiciste esta pregunta a tu compañero desarrollador? – Codesleuth

Respuesta

6

En la mayoría de las implementaciones de navegadores Javascript, la concatenación de cadenas es lenta debido a una copia excesiva.Ver JavaScript: String Concatenation slow performance? Array.join('')?

método preferido es usar una matriz y unirse a:

var pieces = ["You purchased "]; 
pieces.push(num, " widgets."); 
el.innerHTML = pieces.join(''); 

añadido más:

que cree que puede tener un error al acecho en su código: no parece estar escapando sus valores de datos Si alguno de ellos incluye un ampersand, estarías en problemas. Use escape() para todos sus valores de datos.

ps. Y este es un error real que el otro desarrollador se perdió. El problema matemático de cuerdas es un problema de rendimiento/mantenimiento.

Agregado:

me volvió a escribir su sección de composición de correo electrónico (rápidamente). Creo que es más limpio (y será un poco más rápido) cuando se utiliza una matriz de piezas.

.... 
} else { 

var d = []; // the post_data pieces table 

d.push ('services_selected='); // Start the services_selected value 
d.push ('Services Selected: '); 
d.push ($('.l3').text(), ', ', $('.l4').text(), ', ', $('.l5').text(), 
     '; ', $('.l6').text()); 

d.push ('&prices='); // Start the prices value 
d.push ('Prices: '); 
d.push ($('.l7').text(), ', ', $('.l8').text(), ', ', $('.l9').text(), 
     ', ', $('.l10').text()); 

d.push ('&name='); // Start the name value 
d.push ('Name: ', $('input[name="name"]').val()); 

d.push ('&phone='); // Start the phone value 
d.push ('Phone: ', $('input[name="phone"]').val()); 

d.push ('&time='); // Start the timevalue 
d.push ('Preferred contact time: ', 
     $('select[name="contact"] option:selected').val(), 
     $('input[name="ampm"]:checked').val()); 

    $.ajax({ 
     url: 'php/mailer.php', 
     data: d.join(''), 
     type: "POST", 
     success: function() { 
      $('#email_form_box .container').children().fadeOut(500, function() { 
       $('#email_form_box .container').html('<div style="margin:20px auto;text-align:center;width:200px;">yada yada yada<br /><span class="close">Close</span></div>'); 
      }); 
     } 
    }); 
} 
+0

Me encantaría ver un generador de cadenas nativas en la próxima versión de ECMAScript. – ChaosPandion

+0

Esto bien podría ser, pero el JS era permitir que un usuario envíe un correo electrónico a un CSR para contactarse con ellos para obtener información de ventas. Cuando hablamos de un uso tan incoherente (solo se activa a petición del usuario), ¿existe incluso un problema con la concatenación vs. '.join()', además de ser simplemente pedante? – dclowd9901

+0

Leí en alguna parte que solo es lento en IE (hasta IE7). La "combinación de matrices" es lenta en Firefox, pero supongo que esto depende del contexto y de cuánto pueden los motores optimizar la expresión. –

1

Edit: Bien, mi mal, usted no usa + para la concatenación. Editado a continuación:

Edit2: Ok, es JavaScript, de vuelta a +: P


Creo que probablemente refiriéndose a algo como:

$my_html = "<p>" + someVar + "<em>" + somethingImportant + "</em></p>"; 

es decir, utilizando . para la concatenación .

+0

O con '.' en lugar de' + '. –

+1

Esto ni siquiera funcionaría en PHP, porque '+' está reservado para agregar y '.' se usa para concatenación de cadenas. –

+0

Lo siento, me equivoqué. Debería haber sido "javascript" – dclowd9901

1

¿Está almacenando/manipulando datos numéricos usando cadenas? Rara vez es una buena idea.

+0

No es una buena idea, incluso si no los está utilizando como datos numéricos ? – dclowd9901

+0

@ dclowd9901 Imho todos los valores deben almacenarse en una estructura de datos de acuerdo y eso significa, utilizar int (doble ..) para los números. Me gusta porque los números son siempre datos numéricos, incluso si no los usa de esa manera. Pero no sé si otros estarán de acuerdo con mi opinión. – InsertNickHere

+1

@InsertNickHere: El problema es que en y el doble tampoco son estructuras de datos apropiadas para las fracciones decimales (como el dinero).Las cadenas realmente pueden ser una mejor opción allí (por ejemplo, la extensión BCMath de PHP). –

0

Para extender la respuesta de Skilldrick:

No hay nada mal uso de "+" a concat cuerdas (dependiendo de su idioma) hasta que uno de sus variables no es una cadena:

echo 0 + ": hi!<br />"; 
echo 0 .. ": hi!<br />"; 

La primera línea podría dar salida a "0" (mientras intenta convertir la cadena a un número). La segunda línea funciona como se esperaba escribiendo "0: hola!
".

1

Dado que eres nuevo en el desarrollo, lo mejor que puedes hacer es debatir con este desarrollador qué es "String math", cómo puedes identificar cuándo lo estás haciendo nuevamente y cómo evitarlo. Luego, regrese aquí y responda su propia pregunta para que podamos ver lo que realmente es esta "matemática de cadenas", desde la perspectiva de su compañero desarrollador.

+0

No tenga miedo de hacer preguntas. Ningún desarrollador lo sabe todo, y usted aprenderá más de los demás que usted luchando solo. También ayuda a descubrir cómo les gusta hacer las cosas a sus compañeros de trabajo, para evitar argumentos inútiles sobre el estilo de programación. –

+0

@Kristopher Johnson: Fácil de decir, más difícil en la práctica. Es un mundo muy intimidante, esta cosa del desarrollo, y sé que estoy muy por detrás de la mayoría de las demás personas. Sería bueno si tal vez hubiera más tacto involucrado. – dclowd9901

+1

Es lamentable que tantos desarrolladores sean pendejos, pero tendrás que desarrollar una piel gruesa. En última instancia, los desarrolladores te respetarán más si haces las preguntas que necesitas hacer, y hasta se sentirán halagados de que te pidan que te enseñe lo que saben (siempre y cuando no te excedas). –

1

Ya que reetiquetado su pregunta con javascript, entonces su colega podría significar errores en su código que conducen a preguntas como Strange javascript addition problem

Básicamente "1" + 1 evalúa a 11 en javascript, mientras 1 + 1 evalúa a 2. Ahora reemplace el primer argumento de + con una variable y puede obtener un comportamiento inesperado.

+0

Sí, entiendo esto, y analizo los números si llegan a través de datos de cadena, pero todo lo que estaba trabajando con cuerdas, hasta el final, así que no estoy del todo seguro de que esto sea con lo que habría tenido un problema . – dclowd9901

1

es probable que su compañero de trabajo tenga problemas con líneas de este tipo. en teoría, este es el código perfectamente correcto, pero es prácticamente imposible de leer.

services_selected += $('.l3').text() + ', ' + $('.l4').text() + ', ' + $('.l5').text() + '; ' + $('.l6').text(); 

echar un vistazo a la función y la discusión aquí: http://frogsbrain.wordpress.com/2007/04/28/javascript-stringformat-method/

puede añadir fácilmente esta función a sus JS y entonces usted puede cambiar esta línea horrible código para algo como:

services_selected = '{0} , {1}, {2}, {3}; {4}'.format($('.l3').text(), $('.l4').text(), $('.l5').text(), $('.l6').text()); 
+0

Veo que este es el caso. Él es un pegador de código limpio y bonito. Una de esas cabezas Ruby: \ – dclowd9901

0

Esto es lo que pienso cuando escucho "String math". Yo también le gritaba a él.

public String StringAdd (String str1, String str2){ 
    int int1, int2; 
    switch (str1){ 
     case "Zero": 
     int1 = 0; 
     break; 
     case "One": 
     int1 = 1; 
     break; 
     //...etc... 
     default: 
     throw new BadNumberSpellingException("You spelled a number wrong."); 
    } 
    switch (str2){ 
     case "Zero": 
     int2 = 0; 
     break; 
     //...etc... 
    } 

    int result = int1 + int2; 
    switch (result){ 
     case 0: 
     return "Zero"; 
     case 1: 
     return "One"; 
     case 2: 
     return "Two"; 
     //etc.... 
    } 
} 
2

bien, así que aquí está la respuesta que me dijo:

I should have said inline string concatenation/parsing, which is a potential injection vulnerability and a sign of sloppy code or bypassing the framework.

que no encaja exactamente con las otras respuestas que tenemos aquí. Voy a dar el cheque a la respuesta con la mayoría de los votos a favor, ya que es probablemente el más útil, pero solo quería informar.

+1

Gracias por hacernos saber a qué se refería. Por cierto, puedes aceptar tu propia respuesta (pero no obtienes ningún representante cuando lo haces). – GreenMatt

+1

¡Buen trabajo al volver con él! – Irwin