2010-08-03 45 views
5

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

代码中的问题:

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

}); 

编辑:我发现了这里的要点是,这是不是一个标准的开发口语和我也许应该要向谁倾诉给我废话第一的家伙地点。所以我会这样做。多谢你们。我会回复一个答案,或者检查谁已经知道谁。

+4

我想只有你的朋友知道**“弦数学”**的东西:) – Sarfraz 2010-08-03 14:52:01

+6

向我们展示他反对的代码。 – tpdi 2010-08-03 14:53:16

+4

那么,为什么你不问你的开发人员这个问题呢? – Codesleuth 2010-08-03 14:54:32

回答

6

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

首选的方法是使用一个数组,并加入:

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

增加了更多:

我认为你可能有一个潜伏的bug在你的代码:你不似乎逃脱你的数据值。如果其中任何一个包含“&”符号,就会遇到麻烦。对所有数据值使用escape()。

ps。这是其他开发者错过的一个真正的bug。字符串数学问题是一个性能/可维护性问题。

加:

我重写了您的电子邮件作文部分(快速)。我认为使用一个数组时,它会更干净(并且速度会更快)。

.... 
} 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

我很想在ECMAScript的下一个版本中看到一个本地字符串生成器。 – ChaosPandion 2010-08-03 15:10:43

+0

这可能就是这样,但JS是允许用户发送电子邮件给CSR以联系他们获取销售信息。当我们谈论这种不一致的用法时(仅在用户请求时激活),除了一个简单的迂腐之外,还有一个问题是使用串联和'.join()'。 – dclowd9901 2010-08-03 15:13:49

+0

我在某个地方看到它只在IE浏览器中很慢(达到IE7)。 “阵列加入”在Firefox中很慢,但我想这取决于上下文以及引擎可以优化表达式的数量。 – 2010-08-03 15:26:22

1

编辑:好吧,我的坏,你不使用+串联。编辑如下:

EDIT2:好吧,这是JavaScript的,回+:P


我想他很可能指的是这样的:

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

即使用.进行连结。

+0

或用'.'代替'+'。 – 2010-08-03 14:54:34

+1

这在PHP中甚至不起作用,因为'+'是为加法保留的,'.'用于字符串连接。 – 2010-08-03 14:54:43

+0

对不起,贴错了。应该已经是“javascript”了 – dclowd9901 2010-08-03 14:57:48

1

你可能使用字符串存储/操作数值数据吗?这很少是一个好主意。

+0

即使你不使用它们作为数值数据,这不是一个好主意吗? ? – dclowd9901 2010-08-03 15:05:53

+0

@ dclowd9901 Imho所有值都应该存储在相应的数据结构中,这意味着对数字使用int(double ..)。我喜欢它,因为即使您不以这种方式使用数字,数字仍然是数字数据。但我不知道别人是否会同意我的看法。 – InsertNickHere 2010-08-03 15:15:52

+1

@InsertNickHere:问题是into和double都不是十进制小数(例如money)的合适数据结构。字符串实际上可以是更好的选择(例如PHP的BCMath扩展)。 – 2010-08-03 15:19:21

0

为了延长Skilldrick的回答是:

没有什么错用“+”来Concat的字符串(根据您的语言),直到你的变量之一是不是一个字符串:

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

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

1

由于您刚开始接触开发,最好的做法是与开发人员讨论“String math”是什么,您如何识别何时再次使用以及如何避免使用它。 然后,回到这里回答你自己的问题,这样我们就可以从你的开发者的角度看到这个“字符串数学”究竟是什么。

+0

不要害怕提问。没有开发人员知道所有的事情,并且你将通过单独挣扎而从别人身上学到更多东西。这也有助于了解你的同事喜欢做什么事情,以避免编程风格的无谓争论。 – 2010-08-03 15:20:32

+0

@Kristopher Johnson:说起来容易,在实践中更难。这是一个非常恐怖的世界,这是一个发展的事情,而且我知道我远离大多数其他人。如果更多的机智参与,这将是很好的。 – dclowd9901 2010-08-03 15:38:01

+1

不幸的是,如此多的开发者都是混蛋,但你必须开发一个厚厚的皮肤。如果你提出你需要问的问题,最终开发者会更加尊重你,他们甚至会受宠若惊,被要求告诉你他们的知识(只要你不过分)。 – 2010-08-03 15:56:26

1

既然你重新标记使用JavaScript你的问题,那么你的同事可能意味着在你的代码中的错误导致的问题,如Strange javascript addition problem

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

+0

是的,我得到这个,并且如果他们通过字符串数据来解析数字,但是我所使用的所有字符都是字符串,所以我不完全确定这是他会遇到的问题。 。 – dclowd9901 2010-08-03 15:04:56

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()); 
+0

我可以看到这种情况。他是干净漂亮的代码的坚持者。其中一位红宝石头像:\ – dclowd9901 2010-08-03 15:33:11

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.... 
    } 
} 
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.

这并不完全适合其他的答案,我们在这里。我打算用最多的赞扬来给支票给出答案,因为它可能是最有用的,但只是想告知。

+1

感谢您告诉我们他的意思。顺便说一下,你可以接受你自己的答案(但你没有得到任何代表)。 – GreenMatt 2010-08-03 21:50:09

+1

干得好回到他身边! – Irwin 2010-08-04 01:11:52