什么是“字符串数学”,为什么它不好?

时间:2010-08-03 14:50:19

标签: javascript

我最近被一位开发人员指责在我写的应用程序中使用“字符串数学”。我对整个开发工作都很陌生,没有接受过正式培训,我也没有听说过这个问题。它是什么?

有问题的代码:

$('.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>');
                });
            }
        });
    }

});
编辑:我要点到的要点是,这不是一个标准的开发口语,我应该先和那个给我guff的人说话。所以我会这样做。多谢你们。我会回答一下,或者检查一下已经知道的人。

9 个答案:

答案 0 :(得分:6)

在大多数Javascript浏览器实现中,由于过度复制,连接字符串很慢。见JavaScript: String Concatenation slow performance? Array.join('')?

首选方法是使用数组并加入:

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

增加了更多:

我认为您的代码中可能存在潜伏的错误:您似乎没有逃避数据值。如果其中任何一个包括&符号,你就会遇到麻烦。对所有数据值使用escape()。

PS。这是另一个开发人员遗漏的真正错误。字符串数学问题是性能/可维护性问题。

添加了:

我重写了你的电子邮件撰写部分(很快)。我认为使用数组时它更干净(而且速度稍快)。

....
} 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>');
            });
        }
    });
}

答案 1 :(得分:2)

好的,所以这是他告诉我的答案:

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

这与我们在这里得到的其他答案完全不符。我将用最多的投票给出答案,因为它可能是最有用的,但只是想通知。

答案 2 :(得分:1)

编辑:好的,我的不好,你不要使用+进行连接。编辑如下:

编辑2:好的,它是JavaScript,回到+:P


我认为他可能指的是:

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

即。使用.进行连接。

答案 3 :(得分:1)

您是否可以使用字符串存储/操作数值数据?这不是一个好主意。

答案 4 :(得分:1)

由于您不熟悉开发,最好的办法是与开发人员讨论“字符串数学”是什么,如何识别何时再次执行,以及如何避免它。 然后,回到这里回答你自己的问题,这样我们就可以看到这个“字符串数学”究竟是什么 - 从你的开发者的角度来看。

答案 5 :(得分:1)

由于您使用javascript重新提出了问题,因此您的同事可能会在您的代码中出现导致Strange javascript addition problem等问题的错误

基本上"1" + 1在javascript中评估为11,而1 + 1评估为2。现在用变量替换+的第一个参数,你可以得到一些意想不到的行为。

答案 6 :(得分:1)

你的同事可能会遇到这样的问题。理论上这是完全正确的代码,但它几乎不可能阅读。

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

看看这里的功能和讨论: http://frogsbrain.wordpress.com/2007/04/28/javascript-stringformat-method/

您可以轻松地将此功能添加到您的JS中,然后您可以将这些可怕的代码行更改为:

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

答案 7 :(得分:0)

扩展Skilldrick的答案:

使用“+”连接字符串(取决于您的语言)直到您的某个变量不是字符串是没有错的:

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

第一行可能输出“0”(因为它试图将字符串转换为数字)。 第二行按预期编写“0:hi!
”。

答案 8 :(得分:0)

这就是我听到“字符串数学”时的想法。我也会对他大喊大叫。

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....
   }
}
相关问题