2010-08-03 44 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