2011-11-08 59 views
5

下面讓我非常困惑。正如評論指出的那樣,似乎比較自己的工作,但放在一起時,他們不Javascript「==」運算符位於

的同時,應該在同一個月所有天運行,然後通過一個增量I,然後重新開始。

我已經用console.log把整個序列放在一起,試圖找出它,但它沒有任何意義。一切似乎都是平等的,但仍然無法在while語句中進行「==」測試。

var i=0; 
    var currentdate = 0; 
    var currentmonth = 0; 
    var opensmonth = 0; 
    var opens = [ 
    { "date":"3/30/2006","zip":"30038","latitude":"33.676358","longitude":"-84.15381"}, 
    { "date":"4/31/2006","zip":"30519","latitude":"34.089419","longitude":"-83.94701"} 
    ]; 
    intid = setInterval("stepthrough()", 250); 
    function stepthrough() { 
    //figure out first date. 
    if (currentdate == 0) { // we've not been run before 
     currentdate = opens[0]["date"]; 
     currentmonth = currentdate.split("/", 1); 
     console.log("Current Month: >" + currentmonth +"<"); 
    } 
    console.log("Current month: " + currentmonth + " And opensdate: " + opens[i]["date"].split("/", 1)); 

    // 
    // TWILIGHT ZONE ENTERED. 
    // 
    if (currentmonth == 3) { 
     console.log("Current month equals 3."); // PASSES 
    } 
    if (opens[i]["date"].split("/", 1) == 3) { 
     console.log("Opens date equals 3."); // PASSES 
    } 
    // BOTH THE ABOVE TESTS PASS IN CHROME AND SAFARI WHAT THE F*$K JAVASCRIPT 

    while(opens[i]["date"].split("/", 1) == currentmonth) { // WHY DOESNT THIS WORK I HATE COMPUTERS 
     console.log("Trying to add a point one."); 
     addpoint(i); 
     i++; 
     console.log("Trying to add a point."); 
    } 

    //set the date for next iteration 
    currentdate = opens[i]["date"]; 
    currentmonth = currentdate.split("/", 1); 
    console.log ("Current date is now: " + currentdate + " and current month is now: " + currentmonth); 
    jQuery('div#date').text(currentdate); 

    //if (i>=5000) { 
    if (!opens[i]["date"]) { 
     console.log("Clearing interval"); 
     clearInterval(intid); 
     //jQuery('div#date').text("Limited at 5000 records") 
    } 
    } 
+3

嘗試使用'parseInt(stringValue,10)'。 –

+0

如果你在'//爲什麼選擇這個工作'行中使用'===',會發生什麼? [這個答案](http://stackoverflow.com/questions/359494/javascript-vs-does-it-matter-which-equal-operator-i-use/359509#359509)暗示'=='是邪惡的,不可信任。 – CanSpice

+2

我誠實地在這裏看不到問題。 –

回答

4

這裏的問題:​​在Javascript中,由於隱式轉換@馬特介紹。但["1"] != ["1"]在Javascript,因爲你比較兩個陣列,從而兩個對象,和對象比較是隻有當它們指向同一個對象,而不是他們是否指向兩個相同的對象也是如此。

當你分配.split('/', 1),你會得到一個像['3']這樣的數組,而不是字符串"3"(我想你可能會假設)。所以:

currentmonth = currentdate.split("/", 1); // currentmonth is ["3"] 
currentmonth == 3; // true, as described above 
opens[i]["date"].split("/", 1) == 3; // true, because left-hand evals to ["3"] 
opens[i]["date"].split("/", 1) == currentmonth; 
// false, because you're comparing two arrays - ["3"] != ["3"] 

當您當前的代碼解決這個問題,你可以得到的字符串,而不是數組,像這樣:

currentmonth = currentdate.split("/")[0]; // currentmonth is "3" 
opens[i]["date"].split("/")[0] == currentmonth; // true, both sides are "3" 
+0

我應該在繼續之前檢查其餘的答案,我剛剛得出同樣的結論。好答案。 – Nicole

+0

我已經添加了一些[我自己的詳細信息](http://stackoverflow.com/questions/8056317/javascript-operator-lies/8056914#8056914),但是信用讓你首先發現陣列問題。 – Nicole

0

你可以試試這只是爲了知道它是整數還是字符串失敗?

這不是一個很好的解決方案,但它提供了一個線索。

while(opens[i]["date"].split("/", 1) + "str" == currentmonth + "str") 
+1

我會使用'parseInt'來代替。 –

7

JavaScript輸入是隱含的。這意味着如果它認爲你試圖將某些東西當作數字來對待,那麼最好將該對象看作一個數字,即使它是一個布爾值或一個字符串。

當做標準==時,JavaScript將使用隱式轉換來嘗試和匹配類型。這通常會導致意想不到的比較結果。

如果要強制進行強比較,則必須使用===運算符。這就是說,如果您正在檢查字符串的「數字」表示,例如, 「123」,並且想要使用強大的比較,您必須使用parseInt(str,10)將其轉換爲數字;

有關隱式鍵入操作的一些示例,請參閱JavaScript truth table答案。

+0

很好的答案,但實際上並沒有解釋問題的原因,只是最佳實踐。 – nrabinowitz

+0

'Number' [作爲函數調用的構造函數](http://stackoverflow.com/questions/2381399/what-is-the-difference-between-new-number-and-number-in-javascript/2381580#2381580)也適用。 – Nicole

1

請給予好評nrabinowitz's answer,因爲他是第一個,這是正確的。

不過,我想加上潛在的問題的一些細節和Javascript如何處理陣列,數字和字符串之間==隱式轉換。

總結:每種類型在使用==時使用不同類型的規則略有不同。相比號或字符串時,但是當與另一陣列相比不陣列被轉換爲原始值。

詳細

  1. String.split返回一個數組。
  2. 字符串和數字是生的types在Javascript中。其他的是Boolean,Object,Null和Undefined。
  3. 陣列是鍵入對象
  4. ==遵循「Abstract equality comparison algorithm」(x == y
  5. 在您的頭兩次比較,由於類型之一(3)是一個數字,你的條件下,落入以下規則:

    如果Type(x)是要麼字符串編號和Type(y)是Object, 返回比較結果x == ToPrimitive(y)。

    換句話說,它的陣列["3"]轉換爲3,並與3 — 比較(見docs on ToPrimitive

  6. 在你說壞最後情況下,它屬於根據第一條規則(「Type(x)與Type(y)相同」—它們都是Object。然後它評估以下規則:

    如果x和y引用同一個對象,則返回true。否則,返回false。

  7. 它們包含相同的值,但不是相同的對象(每個是String.split呼叫的不同結果),所以結果是

爲了說明:

console.log("3 == [3]?", 3 == [3]); // true 
console.log("3 == ['3']?", 3 == ['3']); // true 
console.log("'3' == [3]?", "3" == [3]); // true 
console.log("'3' == ['3']?", '3' == ['3']); // true 
console.log("[3] == [3]?", [3] == [3]); // false 
console.log("['3'] == ['3']?", ['3'] == ['3']); // false - NOT SAME OBJECT 

var a = ['3']; 
var b = a; // SAME OBJECT 

console.log("a == b?", a == b); // true! 

的溶液,如@nrabinowitz說,是簡單地添加[0]到拆分呼叫結束,使得該值的第一個元素(字符串),而不是數組本身。

+0

良好的細節,並感謝upvote的建議! – nrabinowitz